diff options
author | rmoore1 <rmoore1> | 2006-08-23 19:55:36 +0000 |
---|---|---|
committer | rmoore1 <rmoore1> | 2006-08-23 19:55:36 +0000 |
commit | 62300dae1961d60696162d93501bfb44c1b08f7b (patch) | |
tree | f0afe0c40d1c5a0b39894b8c1f3362a0d9b387d1 /source/components/tables/tbxfroot.c | |
parent | 23d55ffd5499f42f3afbec0dd17903c3d95ed365 (diff) | |
download | acpica-62300dae1961d60696162d93501bfb44c1b08f7b.tar.gz |
The Table Manager component has been completely redesigned and reimplemented. The new design is much simpler, and reduces the overall code and data size of the kernel-resident ACPICA by approximately 5%. Also, it is now possible to obtain the ACPI tables very early during kernel initialization, even before dynamic memory management is initialized.
Diffstat (limited to 'source/components/tables/tbxfroot.c')
-rw-r--r-- | source/components/tables/tbxfroot.c | 589 |
1 files changed, 90 insertions, 499 deletions
diff --git a/source/components/tables/tbxfroot.c b/source/components/tables/tbxfroot.c index de849be97..b656d3d7a 100644 --- a/source/components/tables/tbxfroot.c +++ b/source/components/tables/tbxfroot.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbxfroot - Find the root ACPI table (RSDT) - * $Revision: 1.102 $ + * $Revision: 1.103 $ * *****************************************************************************/ @@ -125,22 +125,21 @@ /* Local prototypes */ -static ACPI_STATUS -AcpiTbFindRsdp ( - ACPI_TABLE_DESC *TableInfo, - UINT32 Flags); - static UINT8 * AcpiTbScanMemoryForRsdp ( UINT8 *StartAddress, UINT32 Length); +static ACPI_STATUS +AcpiTbValidateRsdp ( + ACPI_TABLE_RSDP *Rsdp); + /******************************************************************************* * * FUNCTION: AcpiTbValidateRsdp * - * PARAMETERS: Rsdp - Pointer to unvalidated RSDP + * PARAMETERS: Rsdp - Pointer to unvalidated RSDP * * RETURN: Status * @@ -148,17 +147,20 @@ AcpiTbScanMemoryForRsdp ( * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS AcpiTbValidateRsdp ( - RSDP_DESCRIPTOR *Rsdp) + ACPI_TABLE_RSDP *Rsdp) { ACPI_FUNCTION_ENTRY (); /* - * The signature and checksum must both be correct + * The signature and checksum must both be correct + * + * Note: Sometimes there exists more than one RSDP in memory; the valid + * RSDP has a valid checksum, all others have an invalid checksum. */ - if (ACPI_STRNCMP ((char *) Rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) + if (ACPI_STRNCMP ((char *) Rsdp, ACPI_SIG_RSDP, sizeof (ACPI_SIG_RSDP)-1) != 0) { /* Nope, BAD Signature */ @@ -167,7 +169,7 @@ AcpiTbValidateRsdp ( /* Check the standard checksum */ - if (AcpiTbSumTable (Rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) + if (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { return (AE_BAD_CHECKSUM); } @@ -175,7 +177,7 @@ AcpiTbValidateRsdp ( /* Check extended checksum if table version >= 2 */ if ((Rsdp->Revision >= 2) && - (AcpiTbSumTable (Rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) + (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { return (AE_BAD_CHECKSUM); } @@ -184,359 +186,129 @@ AcpiTbValidateRsdp ( } +#if ACPI_MACHINE_WIDTH != 16 + /******************************************************************************* * - * FUNCTION: AcpiTbFindTable - * - * PARAMETERS: Signature - String with ACPI table signature - * OemId - String with the table OEM ID - * OemTableId - String with the OEM Table ID - * TablePtr - Where the table pointer is returned - * - * RETURN: Status + * FUNCTION: AcpiTbFindRsdp * - * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the - * Signature, OEM ID and OEM Table ID. + * PARAMETERS: TableAddress - Where the table pointer is returned * - ******************************************************************************/ - -ACPI_STATUS -AcpiTbFindTable ( - char *Signature, - char *OemId, - char *OemTableId, - ACPI_TABLE_HEADER **TablePtr) -{ - ACPI_STATUS Status; - ACPI_TABLE_HEADER *Table; - - - ACPI_FUNCTION_TRACE (TbFindTable); - - - /* Validate string lengths */ - - if ((ACPI_STRLEN (Signature) > ACPI_NAME_SIZE) || - (ACPI_STRLEN (OemId) > sizeof (Table->OemId)) || - (ACPI_STRLEN (OemTableId) > sizeof (Table->OemTableId))) - { - return_ACPI_STATUS (AE_AML_STRING_LIMIT); - } - - if (ACPI_COMPARE_NAME (Signature, DSDT_SIG)) - { - /* - * The DSDT pointer is contained in the FADT, not the RSDT. - * This code should suffice, because the only code that would perform - * a "find" on the DSDT is the DataTableRegion() AML opcode -- in - * which case, the DSDT is guaranteed to be already loaded. - * If this becomes insufficient, the FADT will have to be found first. - */ - if (!AcpiGbl_DSDT) - { - return_ACPI_STATUS (AE_NO_ACPI_TABLES); - } - Table = AcpiGbl_DSDT; - } - else - { - /* Find the table */ - - Status = AcpiGetFirmwareTable (Signature, 1, - ACPI_LOGICAL_ADDRESSING, &Table); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - } - - /* Check OemId and OemTableId */ - - if ((OemId[0] && - ACPI_STRNCMP ( - OemId, Table->OemId, - sizeof (Table->OemId))) || - - (OemTableId[0] && - ACPI_STRNCMP ( - OemTableId, Table->OemTableId, - sizeof (Table->OemTableId)))) - { - return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND); - } - - ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n", - Table->Signature)); - - *TablePtr = Table; - return_ACPI_STATUS (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiGetFirmwareTable + * RETURN: Status, RSDP physical address * - * PARAMETERS: Signature - Any ACPI table signature - * Instance - the non zero instance of the table, allows - * support for multiple tables of the same type - * Flags - Physical/Virtual support - * TablePointer - Where a buffer containing the table is - * returned + * DESCRIPTION: Search lower 1Mbyte of memory for the root system descriptor + * pointer structure. If it is found, set *RSDP to point to it. * - * RETURN: Status + * NOTE1: The RSDP must be either in the first 1K of the Extended + * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) + * Only a 32-bit physical address is necessary. * - * DESCRIPTION: This function is called to get an ACPI table. A buffer is - * allocated for the table and returned in TablePointer. - * This table will be a complete table including the header. + * NOTE2: This function is always available, regardless of the + * initialization state of the rest of ACPI. * ******************************************************************************/ ACPI_STATUS -AcpiGetFirmwareTable ( - ACPI_STRING Signature, - UINT32 Instance, - UINT32 Flags, - ACPI_TABLE_HEADER **TablePointer) +AcpiFindRootPointer ( + ACPI_NATIVE_UINT *TableAddress) { - ACPI_STATUS Status; - ACPI_POINTER Address; - ACPI_TABLE_HEADER *Header = NULL; - ACPI_TABLE_DESC *TableInfo = NULL; - ACPI_TABLE_DESC *RsdtInfo; - UINT32 TableCount; - UINT32 i; - UINT32 j; - + UINT8 *TablePtr; + UINT8 *MemRover; + UINT32 PhysicalAddress; - ACPI_FUNCTION_TRACE (AcpiGetFirmwareTable); + ACPI_FUNCTION_TRACE (AcpiFindRootPointer); - /* - * Ensure that at least the table manager is initialized. We don't - * require that the entire ACPI subsystem is up for this interface. - * If we have a buffer, we must have a length too - */ - if ((Instance == 0) || - (!Signature) || - (!TablePointer)) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - /* Ensure that we have a RSDP */ + /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ - if (!AcpiGbl_RSDP) + TablePtr = AcpiOsMapMemory ( + (ACPI_PHYSICAL_ADDRESS) ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH); + if (!TablePtr) { - /* Get the RSDP */ + ACPI_ERROR ((AE_INFO, + "Could not map memory at %8.8X for length %X", + ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); - Status = AcpiOsGetRootPointer (Flags, &Address); - if (ACPI_FAILURE (Status)) - { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n")); - return_ACPI_STATUS (AE_NO_ACPI_TABLES); - } - - /* Map and validate the RSDP */ - - if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) - { - Status = AcpiOsMapMemory (Address.Pointer.Physical, - sizeof (RSDP_DESCRIPTOR), (void *) &AcpiGbl_RSDP); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - } - else - { - AcpiGbl_RSDP = Address.Pointer.Logical; - } - - /* The RDSP signature and checksum must both be correct */ - - Status = AcpiTbValidateRsdp (AcpiGbl_RSDP); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - } - - /* Get the RSDT address via the RSDP */ - - AcpiTbGetRsdtAddress (&Address); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "RSDP located at %p, RSDT physical=%8.8X%8.8X\n", - AcpiGbl_RSDP, - ACPI_FORMAT_UINT64 (Address.Pointer.Value))); - - /* Insert ProcessorMode flags */ - - Address.PointerType |= Flags; - - /* Get and validate the RSDT */ - - RsdtInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_TABLE_DESC)); - if (!RsdtInfo) - { return_ACPI_STATUS (AE_NO_MEMORY); } - Status = AcpiTbGetTable (&Address, RsdtInfo); - if (ACPI_FAILURE (Status)) - { - goto Cleanup; - } + ACPI_MOVE_16_TO_32 (&PhysicalAddress, TablePtr); - Status = AcpiTbValidateRsdt (RsdtInfo->Pointer); - if (ACPI_FAILURE (Status)) - { - goto Cleanup; - } + /* Convert segment part to physical address */ - /* Allocate a scratch table header and table descriptor */ + PhysicalAddress <<= 4; + AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_PTR_LENGTH); - Header = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER)); - if (!Header) - { - Status = AE_NO_MEMORY; - goto Cleanup; - } + /* EBDA present? */ - TableInfo = ACPI_ALLOCATE (sizeof (ACPI_TABLE_DESC)); - if (!TableInfo) - { - Status = AE_NO_MEMORY; - goto Cleanup; - } - - /* Get the number of table pointers within the RSDT */ - - TableCount = AcpiTbGetTableCount (AcpiGbl_RSDP, RsdtInfo->Pointer); - Address.PointerType = AcpiGbl_TableFlags | Flags; - - /* - * Search the RSDT/XSDT for the correct instance of the - * requested table - */ - for (i = 0, j = 0; i < TableCount; i++) + if (PhysicalAddress > 0x400) { /* - * Get the next table pointer, handle RSDT vs. XSDT - * RSDT pointers are 32 bits, XSDT pointers are 64 bits + * 1b) Search EBDA paragraphs (EBDA is required to be a + * minimum of 1K length) */ - if (AcpiGbl_RootTableType == ACPI_TABLE_TYPE_RSDT) - { - Address.Pointer.Value = (ACPI_CAST_PTR ( - RSDT_DESCRIPTOR, RsdtInfo->Pointer))->TableOffsetEntry[i]; - } - else + TablePtr = AcpiOsMapMemory ( + (ACPI_NATIVE_UINT) PhysicalAddress, + ACPI_EBDA_WINDOW_SIZE); + if (!TablePtr) { - Address.Pointer.Value = ACPI_GET_ADDRESS ((ACPI_CAST_PTR ( - XSDT_DESCRIPTOR, RsdtInfo->Pointer))->TableOffsetEntry[i]); + ACPI_ERROR ((AE_INFO, + "Could not map memory at %8.8X for length %X", + PhysicalAddress, ACPI_EBDA_WINDOW_SIZE)); + + return_ACPI_STATUS (AE_NO_MEMORY); } - /* Get the table header */ + MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_EBDA_WINDOW_SIZE); + AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_WINDOW_SIZE); - Status = AcpiTbGetTableHeader (&Address, Header); - if (ACPI_FAILURE (Status)) + if (MemRover) { - goto Cleanup; - } + /* Return the physical address */ - /* Compare table signatures and table instance */ + PhysicalAddress += (UINT32) ACPI_PTR_DIFF (MemRover, TablePtr); - if (ACPI_COMPARE_NAME (Header->Signature, Signature)) - { - /* An instance of the table was found */ - - j++; - if (j >= Instance) - { - /* Found the correct instance, get the entire table */ - - Status = AcpiTbGetTableBody (&Address, Header, TableInfo); - if (ACPI_FAILURE (Status)) - { - goto Cleanup; - } - - *TablePointer = TableInfo->Pointer; - goto Cleanup; - } + *TableAddress = PhysicalAddress; + return_ACPI_STATUS (AE_OK); } } - /* Did not find the table */ - - Status = AE_NOT_EXIST; - + /* + * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh + */ + TablePtr = AcpiOsMapMemory ( + (ACPI_PHYSICAL_ADDRESS) ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE); -Cleanup: - if (RsdtInfo->Pointer) + if (!TablePtr) { - AcpiOsUnmapMemory (RsdtInfo->Pointer, - (ACPI_SIZE) RsdtInfo->Pointer->Length); - } - ACPI_FREE (RsdtInfo); + ACPI_ERROR ((AE_INFO, + "Could not map memory at %8.8X for length %X", + ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); - if (Header) - { - ACPI_FREE (Header); - } - if (TableInfo) - { - ACPI_FREE (TableInfo); + return_ACPI_STATUS (AE_NO_MEMORY); } - return_ACPI_STATUS (Status); -} -ACPI_EXPORT_SYMBOL (AcpiGetFirmwareTable) - - -/* TBD: Move to a new file */ - -#if ACPI_MACHINE_WIDTH != 16 + MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); + AcpiOsUnmapMemory (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); -/******************************************************************************* - * - * FUNCTION: AcpiFindRootPointer - * - * PARAMETERS: Flags - Logical/Physical addressing - * RsdpAddress - Where to place the RSDP address - * - * RETURN: Status, Physical address of the RSDP - * - * DESCRIPTION: Find the RSDP - * - ******************************************************************************/ - -ACPI_STATUS -AcpiFindRootPointer ( - UINT32 Flags, - ACPI_POINTER *RsdpAddress) -{ - ACPI_TABLE_DESC TableInfo; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (AcpiFindRootPointer); - - - /* Get the RSDP */ - - Status = AcpiTbFindRsdp (&TableInfo, Flags); - if (ACPI_FAILURE (Status)) + if (MemRover) { - ACPI_EXCEPTION ((AE_INFO, Status, - "RSDP structure not found - Flags=%X", Flags)); + /* Return the physical address */ - return_ACPI_STATUS (AE_NO_ACPI_TABLES); + PhysicalAddress = (UINT32) + (ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (MemRover, TablePtr)); + + *TableAddress = PhysicalAddress; + return_ACPI_STATUS (AE_OK); } - RsdpAddress->PointerType = ACPI_PHYSICAL_POINTER; - RsdpAddress->Pointer.Physical = TableInfo.PhysicalAddress; - return_ACPI_STATUS (AE_OK); + /* A valid RSDP was not found */ + + ACPI_ERROR ((AE_INFO, "A valid RSDP was not found")); + return_ACPI_STATUS (AE_NOT_FOUND); } ACPI_EXPORT_SYMBOL (AcpiFindRootPointer) @@ -577,7 +349,7 @@ AcpiTbScanMemoryForRsdp ( { /* The RSDP signature and checksum must both be correct */ - Status = AcpiTbValidateRsdp (ACPI_CAST_PTR (RSDP_DESCRIPTOR, MemRover)); + Status = AcpiTbValidateRsdp (ACPI_CAST_PTR (ACPI_TABLE_RSDP, MemRover)); if (ACPI_SUCCESS (Status)) { /* Sig and checksum valid, we have found a real RSDP */ @@ -598,186 +370,5 @@ AcpiTbScanMemoryForRsdp ( return_PTR (NULL); } - -/******************************************************************************* - * - * FUNCTION: AcpiTbFindRsdp - * - * PARAMETERS: TableInfo - Where the table info is returned - * Flags - Current memory mode (logical vs. - * physical addressing) - * - * RETURN: Status, RSDP physical address - * - * DESCRIPTION: Search lower 1Mbyte of memory for the root system descriptor - * pointer structure. If it is found, set *RSDP to point to it. - * - * NOTE1: The RSDP must be either in the first 1K of the Extended - * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) - * Only a 32-bit physical address is necessary. - * - * NOTE2: This function is always available, regardless of the - * initialization state of the rest of ACPI. - * - ******************************************************************************/ - -static ACPI_STATUS -AcpiTbFindRsdp ( - ACPI_TABLE_DESC *TableInfo, - UINT32 Flags) -{ - UINT8 *TablePtr; - UINT8 *MemRover; - UINT32 PhysicalAddress; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (TbFindRsdp); - - - /* - * Scan supports either logical addressing or physical addressing - */ - if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) - { - /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ - - Status = AcpiOsMapMemory ( - (ACPI_PHYSICAL_ADDRESS) ACPI_EBDA_PTR_LOCATION, - ACPI_EBDA_PTR_LENGTH, (void *) &TablePtr); - if (ACPI_FAILURE (Status)) - { - ACPI_ERROR ((AE_INFO, - "Could not map memory at %8.8X for length %X", - ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); - - return_ACPI_STATUS (Status); - } - - ACPI_MOVE_16_TO_32 (&PhysicalAddress, TablePtr); - - /* Convert segment part to physical address */ - - PhysicalAddress <<= 4; - AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_PTR_LENGTH); - - /* EBDA present? */ - - if (PhysicalAddress > 0x400) - { - /* - * 1b) Search EBDA paragraphs (EBDA is required to be a - * minimum of 1K length) - */ - Status = AcpiOsMapMemory ( - (ACPI_PHYSICAL_ADDRESS) PhysicalAddress, - ACPI_EBDA_WINDOW_SIZE, (void *) &TablePtr); - if (ACPI_FAILURE (Status)) - { - ACPI_ERROR ((AE_INFO, - "Could not map memory at %8.8X for length %X", - PhysicalAddress, ACPI_EBDA_WINDOW_SIZE)); - - return_ACPI_STATUS (Status); - } - - MemRover = AcpiTbScanMemoryForRsdp (TablePtr, - ACPI_EBDA_WINDOW_SIZE); - AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_WINDOW_SIZE); - - if (MemRover) - { - /* Return the physical address */ - - PhysicalAddress += (UINT32) ACPI_PTR_DIFF (MemRover, TablePtr); - - TableInfo->PhysicalAddress = - (ACPI_PHYSICAL_ADDRESS) PhysicalAddress; - return_ACPI_STATUS (AE_OK); - } - } - - /* - * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh - */ - Status = AcpiOsMapMemory ( - (ACPI_PHYSICAL_ADDRESS) ACPI_HI_RSDP_WINDOW_BASE, - ACPI_HI_RSDP_WINDOW_SIZE, (void *) &TablePtr); - - if (ACPI_FAILURE (Status)) - { - ACPI_ERROR ((AE_INFO, - "Could not map memory at %8.8X for length %X", - ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); - - return_ACPI_STATUS (Status); - } - - MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); - AcpiOsUnmapMemory (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); - - if (MemRover) - { - /* Return the physical address */ - - PhysicalAddress = (UINT32) - (ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (MemRover, TablePtr)); - - TableInfo->PhysicalAddress = - (ACPI_PHYSICAL_ADDRESS) PhysicalAddress; - return_ACPI_STATUS (AE_OK); - } - } - - /* - * Physical addressing - */ - else - { - /* 1a) Get the location of the EBDA */ - - ACPI_MOVE_16_TO_32 (&PhysicalAddress, ACPI_EBDA_PTR_LOCATION); - PhysicalAddress <<= 4; /* Convert segment to physical address */ - - /* EBDA present? */ - - if (PhysicalAddress > 0x400) - { - /* - * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of - * 1K length) - */ - MemRover = AcpiTbScanMemoryForRsdp ( - ACPI_PHYSADDR_TO_PTR (PhysicalAddress), - ACPI_EBDA_WINDOW_SIZE); - if (MemRover) - { - /* Return the physical address */ - - TableInfo->PhysicalAddress = ACPI_TO_INTEGER (MemRover); - return_ACPI_STATUS (AE_OK); - } - } - - /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ - - MemRover = AcpiTbScanMemoryForRsdp ( - ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE), - ACPI_HI_RSDP_WINDOW_SIZE); - if (MemRover) - { - /* Found it, return the physical address */ - - TableInfo->PhysicalAddress = ACPI_TO_INTEGER (MemRover); - return_ACPI_STATUS (AE_OK); - } - } - - /* A valid RSDP was not found */ - - ACPI_ERROR ((AE_INFO, "No valid RSDP was found")); - return_ACPI_STATUS (AE_NOT_FOUND); -} - #endif |