#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbxfroot")
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_find_rsdp (
+ struct acpi_table_desc *table_info,
+ u32 flags);
+
+static u8 *
+acpi_tb_scan_memory_for_rsdp (
+ u8 *start_address,
+ u32 length);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_validate_rsdp
+ *
+ * PARAMETERS: Rsdp - Pointer to unvalidated RSDP
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validate the RSDP (ptr)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_validate_rsdp (
+ struct rsdp_descriptor *rsdp)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * The signature and checksum must both be correct
+ */
+ if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+ /* Nope, BAD Signature */
+
+ return (AE_BAD_SIGNATURE);
+ }
+
+ /* Check the standard checksum */
+
+ if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
+ return (AE_BAD_CHECKSUM);
+ }
+
+ /* Check extended checksum if table version >= 2 */
+
+ if ((rsdp->revision >= 2) &&
+ (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
+ return (AE_BAD_CHECKSUM);
+ }
+
+ return (AE_OK);
+}
+
/*******************************************************************************
*
*
* PARAMETERS: Signature - String with ACPI table signature
* oem_id - String with the table OEM ID
- * oem_table_id - String with the OEM Table ID.
+ * oem_table_id - String with the OEM Table ID
+ * table_ptr - Where the table pointer is returned
*
* RETURN: Status
*
if (!acpi_gbl_DSDT) {
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
-
table = acpi_gbl_DSDT;
}
else {
/* Find the table */
status = acpi_get_firmware_table (signature, 1,
- ACPI_LOGICAL_ADDRESSING, &table);
+ ACPI_LOGICAL_ADDRESSING, &table);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Check oem_id and oem_table_id */
- if ((oem_id[0] && ACPI_STRNCMP (
- oem_id, table->oem_id, sizeof (table->oem_id))) ||
+ if ((oem_id[0] && ACPI_STRNCMP (
+ oem_id, table->oem_id,
+ sizeof (table->oem_id))) ||
+
(oem_table_id[0] && ACPI_STRNCMP (
- oem_table_id, table->oem_table_id, sizeof (table->oem_table_id)))) {
+ oem_table_id, table->oem_table_id,
+ sizeof (table->oem_table_id)))) {
return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n", table->signature));
+ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
+ table->signature));
+
*table_ptr = table;
return_ACPI_STATUS (AE_OK);
}
/* Map and validate the RSDP */
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
- status = acpi_os_map_memory (address.pointer.physical, sizeof (struct rsdp_descriptor),
- (void *) &acpi_gbl_RSDP);
+ status = acpi_os_map_memory (address.pointer.physical,
+ sizeof (struct rsdp_descriptor), (void *) &acpi_gbl_RSDP);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
acpi_gbl_RSDP = address.pointer.logical;
}
- /* The signature and checksum must both be correct */
-
- if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
- /* Nope, BAD Signature */
-
- return_ACPI_STATUS (AE_BAD_SIGNATURE);
- }
-
- if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
- /* Nope, BAD Checksum */
+ /* The RDSP signature and checksum must both be correct */
- return_ACPI_STATUS (AE_BAD_CHECKSUM);
+ status = acpi_tb_validate_rsdp (acpi_gbl_RSDP);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
}
}
* requested table
*/
for (i = 0, j = 0; i < table_count; i++) {
- /* Get the next table pointer, handle RSDT vs. XSDT */
-
- if (acpi_gbl_RSDP->revision < 2) {
+ /*
+ * Get the next table pointer, handle RSDT vs. XSDT
+ * RSDT pointers are 32 bits, XSDT pointers are 64 bits
+ */
+ if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
address.pointer.value = (ACPI_CAST_PTR (
RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
}
cleanup:
- acpi_os_unmap_memory (rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length);
+ if (rsdt_info->pointer) {
+ acpi_os_unmap_memory (rsdt_info->pointer,
+ (acpi_size) rsdt_info->pointer->length);
+ }
ACPI_MEM_FREE (rsdt_info);
if (header) {
*
* FUNCTION: acpi_find_root_pointer
*
- * PARAMETERS: **rsdp_address - Where to place the RSDP address
- * Flags - Logical/Physical addressing
+ * PARAMETERS: Flags - Logical/Physical addressing
+ * rsdp_address - Where to place the RSDP address
*
* RETURN: Status, Physical address of the RSDP
*
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"RSDP structure not found, %s Flags=%X\n",
acpi_format_exception (status), flags));
+
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
*
******************************************************************************/
-u8 *
+static u8 *
acpi_tb_scan_memory_for_rsdp (
u8 *start_address,
u32 length)
{
+ acpi_status status;
u8 *mem_rover;
u8 *end_address;
- u8 checksum;
ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp");
for (mem_rover = start_address; mem_rover < end_address;
mem_rover += ACPI_RSDP_SCAN_STEP) {
- /* The signature and checksum must both be correct */
-
- if (ACPI_STRNCMP ((char *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
- /* No signature match, keep looking */
-
- continue;
- }
-
- /* Signature matches, check the appropriate checksum */
-
- if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) {
- /* ACPI version 1.0 */
-
- checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH);
- }
- else {
- /* Post ACPI 1.0, use extended_checksum */
-
- checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH);
- }
+ /* The RSDP signature and checksum must both be correct */
- if (checksum == 0) {
- /* Checksum valid, we have found a valid RSDP */
+ status = acpi_tb_validate_rsdp (ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover));
+ if (ACPI_SUCCESS (status)) {
+ /* Sig and checksum valid, we have found a real RSDP */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"RSDP located at physical address %p\n", mem_rover));
return_PTR (mem_rover);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Found an RSDP at physical address %p, but it has a bad checksum\n",
- mem_rover));
+ /* No sig match or bad checksum, keep searching */
}
/* Searched entire block, no RSDP was found */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Searched entire block, no valid RSDP was found.\n"));
+ "Searched entire block from %p, valid RSDP was not found\n",
+ start_address));
return_PTR (NULL);
}
*
* FUNCTION: acpi_tb_find_rsdp
*
- * PARAMETERS: *table_info - Where the table info is returned
+ * PARAMETERS: table_info - Where the table info is returned
* Flags - Current memory mode (logical vs.
* physical addressing)
*
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_tb_find_rsdp (
struct acpi_table_desc *table_info,
u32 flags)
/*
- * Scan supports either 1) Logical addressing or 2) Physical addressing
+ * Scan supports either logical addressing or physical addressing
*/
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
- /*
- * 1a) Get the location of the EBDA
- */
- status = acpi_os_map_memory ((acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
- ACPI_EBDA_PTR_LENGTH,
- (void *) &table_ptr);
+ /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
+
+ status = acpi_os_map_memory (
+ (acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
+ ACPI_EBDA_PTR_LENGTH, (void *) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not map memory at %8.8X for length %X\n",
ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
+
return_ACPI_STATUS (status);
}
ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);
- physical_address <<= 4; /* Convert segment to physical address */
+
+ /* Convert segment part to physical address */
+
+ physical_address <<= 4;
acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);
/* EBDA present? */
if (physical_address > 0x400) {
/*
- * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+ * 1b) Search EBDA paragraphs (EBDa is required to be a
+ * minimum of 1_k length)
*/
- status = acpi_os_map_memory ((acpi_physical_address) physical_address,
- ACPI_EBDA_WINDOW_SIZE,
- (void *) &table_ptr);
+ status = acpi_os_map_memory (
+ (acpi_physical_address) physical_address,
+ ACPI_EBDA_WINDOW_SIZE, (void *) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not map memory at %8.8X for length %X\n",
physical_address, ACPI_EBDA_WINDOW_SIZE));
+
return_ACPI_STATUS (status);
}
- mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_EBDA_WINDOW_SIZE);
+ mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr,
+ ACPI_EBDA_WINDOW_SIZE);
acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) {
- /* Found it, return the physical address */
+ /* Return the physical address */
physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
- table_info->physical_address = (acpi_physical_address) physical_address;
+ table_info->physical_address =
+ (acpi_physical_address) physical_address;
return_ACPI_STATUS (AE_OK);
}
}
/*
* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
*/
- status = acpi_os_map_memory ((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
- ACPI_HI_RSDP_WINDOW_SIZE,
- (void *) &table_ptr);
+ status = acpi_os_map_memory (
+ (acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
+ ACPI_HI_RSDP_WINDOW_SIZE, (void *) &table_ptr);
+
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not map memory at %8.8X for length %X\n",
ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
+
return_ACPI_STATUS (status);
}
acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
if (mem_rover) {
- /* Found it, return the physical address */
+ /* Return the physical address */
- physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
+ physical_address =
+ ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
- table_info->physical_address = (acpi_physical_address) physical_address;
+ table_info->physical_address =
+ (acpi_physical_address) physical_address;
return_ACPI_STATUS (AE_OK);
}
}
* Physical addressing
*/
else {
- /*
- * 1a) Get the location of the EBDA
- */
+ /* 1a) Get the location of the EBDA */
+
ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
physical_address <<= 4; /* Convert segment to physical address */
if (physical_address > 0x400) {
/*
- * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+ * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of
+ * 1_k length)
*/
- mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (physical_address),
+ mem_rover = acpi_tb_scan_memory_for_rsdp (
+ ACPI_PHYSADDR_TO_PTR (physical_address),
ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) {
- /* Found it, return the physical address */
+ /* Return the physical address */
table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
return_ACPI_STATUS (AE_OK);
}
}
- /*
- * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
- */
- mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
+ /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
+
+ mem_rover = acpi_tb_scan_memory_for_rsdp (
+ ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
ACPI_HI_RSDP_WINDOW_SIZE);
if (mem_rover) {
/* Found it, return the physical address */
}
}
- /* RSDP signature was not found */
+ /* A valid RSDP was not found */
+ ACPI_REPORT_ERROR (("No valid RSDP was found\n"));
return_ACPI_STATUS (AE_NOT_FOUND);
}