tbutils.c revision 83174
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: tbutils - Table manipulation utilities 483174Smsmith * $Revision: 40 $ 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 867754Smsmith/****************************************************************************** 967754Smsmith * 1067754Smsmith * 1. Copyright Notice 1167754Smsmith * 1271867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1370243Smsmith * All rights reserved. 1467754Smsmith * 1567754Smsmith * 2. License 1667754Smsmith * 1767754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1867754Smsmith * rights. You may have additional license terms from the party that provided 1967754Smsmith * you this software, covering your right to use that party's intellectual 2067754Smsmith * property rights. 2167754Smsmith * 2267754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2367754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2467754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2567754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2667754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2767754Smsmith * Code in any form, with the right to sublicense such rights; and 2867754Smsmith * 2967754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3067754Smsmith * license (with the right to sublicense), under only those claims of Intel 3167754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3267754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3367754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3467754Smsmith * license, and in no event shall the patent license extend to any additions 3567754Smsmith * to or modifications of the Original Intel Code. No other license or right 3667754Smsmith * is granted directly or by implication, estoppel or otherwise; 3767754Smsmith * 3867754Smsmith * The above copyright and patent license is granted only if the following 3967754Smsmith * conditions are met: 4067754Smsmith * 4167754Smsmith * 3. Conditions 4267754Smsmith * 4367754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4467754Smsmith * Redistribution of source code of any substantial portion of the Covered 4567754Smsmith * Code or modification with rights to further distribute source must include 4667754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4767754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4867754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4967754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5067754Smsmith * Code and the date of any change. Licensee must include in that file the 5167754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5267754Smsmith * must include a prominent statement that the modification is derived, 5367754Smsmith * directly or indirectly, from Original Intel Code. 5467754Smsmith * 5567754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5667754Smsmith * Redistribution of source code of any substantial portion of the Covered 5767754Smsmith * Code or modification without rights to further distribute source must 5867754Smsmith * include the following Disclaimer and Export Compliance provision in the 5967754Smsmith * documentation and/or other materials provided with distribution. In 6067754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6167754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6267754Smsmith * license from Licensee to its licensee is limited to the intellectual 6367754Smsmith * property embodied in the software Licensee provides to its licensee, and 6467754Smsmith * not to intellectual property embodied in modifications its licensee may 6567754Smsmith * make. 6667754Smsmith * 6767754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6867754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6967754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7067754Smsmith * provision in the documentation and/or other materials provided with the 7167754Smsmith * distribution. 7267754Smsmith * 7367754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7467754Smsmith * Intel Code. 7567754Smsmith * 7667754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7767754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7867754Smsmith * other dealings in products derived from or relating to the Covered Code 7967754Smsmith * without prior written authorization from Intel. 8067754Smsmith * 8167754Smsmith * 4. Disclaimer and Export Compliance 8267754Smsmith * 8367754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8467754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8567754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8667754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8767754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8867754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8967754Smsmith * PARTICULAR PURPOSE. 9067754Smsmith * 9167754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9267754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9367754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9467754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9567754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9667754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9767754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9867754Smsmith * LIMITED REMEDY. 9967754Smsmith * 10067754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10167754Smsmith * software or system incorporating such software without first obtaining any 10267754Smsmith * required license or other approval from the U. S. Department of Commerce or 10367754Smsmith * any other agency or department of the United States Government. In the 10467754Smsmith * event Licensee exports any such software from the United States or 10567754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10667754Smsmith * ensure that the distribution and export/re-export of the software is in 10767754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10867754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10967754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11067754Smsmith * software, or service, directly or indirectly, to any country for which the 11167754Smsmith * United States government or any agency thereof requires an export license, 11267754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11367754Smsmith * such license, approval or letter. 11467754Smsmith * 11567754Smsmith *****************************************************************************/ 11667754Smsmith 11767754Smsmith#define __TBUTILS_C__ 11867754Smsmith 11967754Smsmith#include "acpi.h" 12067754Smsmith#include "actables.h" 12167754Smsmith#include "acinterp.h" 12267754Smsmith 12367754Smsmith 12477424Smsmith#define _COMPONENT ACPI_TABLES 12567754Smsmith MODULE_NAME ("tbutils") 12667754Smsmith 12767754Smsmith 12867754Smsmith/******************************************************************************* 12967754Smsmith * 13067754Smsmith * FUNCTION: AcpiTbHandleToObject 13167754Smsmith * 13267754Smsmith * PARAMETERS: TableId - Id for which the function is searching 13367754Smsmith * TableDesc - Pointer to return the matching table 13467754Smsmith * descriptor. 13567754Smsmith * 13667754Smsmith * RETURN: Search the tables to find one with a matching TableId and 13767754Smsmith * return a pointer to that table descriptor. 13867754Smsmith * 13967754Smsmith ******************************************************************************/ 14067754Smsmith 14167754SmsmithACPI_STATUS 14267754SmsmithAcpiTbHandleToObject ( 14367754Smsmith UINT16 TableId, 14467754Smsmith ACPI_TABLE_DESC **TableDesc) 14567754Smsmith{ 14667754Smsmith UINT32 i; 14767754Smsmith ACPI_TABLE_DESC *ListHead; 14867754Smsmith 14983174Smsmith 15082367Smsmith PROC_NAME ("TbHandleToObject"); 15167754Smsmith 15282367Smsmith 15367754Smsmith for (i = 0; i < ACPI_TABLE_MAX; i++) 15467754Smsmith { 15567754Smsmith ListHead = &AcpiGbl_AcpiTables[i]; 15667754Smsmith do 15767754Smsmith { 15867754Smsmith if (ListHead->TableId == TableId) 15967754Smsmith { 16067754Smsmith *TableDesc = ListHead; 16167754Smsmith return (AE_OK); 16267754Smsmith } 16367754Smsmith 16467754Smsmith ListHead = ListHead->Next; 16567754Smsmith 16667754Smsmith } while (ListHead != &AcpiGbl_AcpiTables[i]); 16767754Smsmith } 16867754Smsmith 16967754Smsmith 17082367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "TableId=%X does not exist\n", TableId)); 17167754Smsmith return (AE_BAD_PARAMETER); 17267754Smsmith} 17367754Smsmith 17467754Smsmith 17567754Smsmith/******************************************************************************* 17667754Smsmith * 17767754Smsmith * FUNCTION: AcpiTbSystemTablePointer 17867754Smsmith * 17967754Smsmith * PARAMETERS: *Where - Pointer to be examined 18067754Smsmith * 18167754Smsmith * RETURN: TRUE if Where is within the AML stream (in one of the ACPI 18267754Smsmith * system tables such as the DSDT or an SSDT.) 18367754Smsmith * FALSE otherwise 18467754Smsmith * 18567754Smsmith ******************************************************************************/ 18667754Smsmith 18767754SmsmithBOOLEAN 18867754SmsmithAcpiTbSystemTablePointer ( 18967754Smsmith void *Where) 19067754Smsmith{ 19167754Smsmith UINT32 i; 19267754Smsmith ACPI_TABLE_DESC *TableDesc; 19367754Smsmith ACPI_TABLE_HEADER *Table; 19467754Smsmith 19567754Smsmith 19667754Smsmith /* No function trace, called too often! */ 19767754Smsmith 19867754Smsmith 19967754Smsmith /* Ignore null pointer */ 20067754Smsmith 20167754Smsmith if (!Where) 20267754Smsmith { 20367754Smsmith return (FALSE); 20467754Smsmith } 20567754Smsmith 20667754Smsmith 20767754Smsmith /* Check for a pointer within the DSDT */ 20867754Smsmith 20967754Smsmith if ((AcpiGbl_DSDT) && 21067754Smsmith (IS_IN_ACPI_TABLE (Where, AcpiGbl_DSDT))) 21167754Smsmith { 21267754Smsmith return (TRUE); 21367754Smsmith } 21467754Smsmith 21567754Smsmith 21667754Smsmith /* Check each of the loaded SSDTs (if any)*/ 21767754Smsmith 21867754Smsmith TableDesc = &AcpiGbl_AcpiTables[ACPI_TABLE_SSDT]; 21967754Smsmith 22067754Smsmith for (i = 0; i < AcpiGbl_AcpiTables[ACPI_TABLE_SSDT].Count; i++) 22167754Smsmith { 22267754Smsmith Table = TableDesc->Pointer; 22367754Smsmith 22467754Smsmith if (IS_IN_ACPI_TABLE (Where, Table)) 22567754Smsmith { 22667754Smsmith return (TRUE); 22767754Smsmith } 22867754Smsmith 22967754Smsmith TableDesc = TableDesc->Next; 23067754Smsmith } 23167754Smsmith 23267754Smsmith 23367754Smsmith /* Check each of the loaded PSDTs (if any)*/ 23467754Smsmith 23567754Smsmith TableDesc = &AcpiGbl_AcpiTables[ACPI_TABLE_PSDT]; 23667754Smsmith 23767754Smsmith for (i = 0; i < AcpiGbl_AcpiTables[ACPI_TABLE_PSDT].Count; i++) 23867754Smsmith { 23967754Smsmith Table = TableDesc->Pointer; 24067754Smsmith 24167754Smsmith if (IS_IN_ACPI_TABLE (Where, Table)) 24267754Smsmith { 24367754Smsmith return (TRUE); 24467754Smsmith } 24567754Smsmith 24667754Smsmith TableDesc = TableDesc->Next; 24767754Smsmith } 24867754Smsmith 24967754Smsmith 25067754Smsmith /* Pointer does not point into any system table */ 25167754Smsmith 25267754Smsmith return (FALSE); 25367754Smsmith} 25467754Smsmith 25567754Smsmith 25667754Smsmith/******************************************************************************* 25767754Smsmith * 25867754Smsmith * FUNCTION: AcpiTbValidateTableHeader 25967754Smsmith * 26067754Smsmith * PARAMETERS: TableHeader - Logical pointer to the table 26167754Smsmith * 26267754Smsmith * RETURN: Status 26367754Smsmith * 26467754Smsmith * DESCRIPTION: Check an ACPI table header for validity 26567754Smsmith * 26667754Smsmith * NOTE: Table pointers are validated as follows: 26767754Smsmith * 1) Table pointer must point to valid physical memory 26867754Smsmith * 2) Signature must be 4 ASCII chars, even if we don't recognize the 26967754Smsmith * name 27067754Smsmith * 3) Table must be readable for length specified in the header 27167754Smsmith * 4) Table checksum must be valid (with the exception of the FACS 27267754Smsmith * which has no checksum for some odd reason) 27367754Smsmith * 27467754Smsmith ******************************************************************************/ 27567754Smsmith 27667754SmsmithACPI_STATUS 27767754SmsmithAcpiTbValidateTableHeader ( 27867754Smsmith ACPI_TABLE_HEADER *TableHeader) 27967754Smsmith{ 28067754Smsmith ACPI_NAME Signature; 28167754Smsmith 28267754Smsmith 28377424Smsmith PROC_NAME ("TbValidateTableHeader"); 28477424Smsmith 28577424Smsmith 28667754Smsmith /* Verify that this is a valid address */ 28767754Smsmith 28867754Smsmith if (!AcpiOsReadable (TableHeader, sizeof (ACPI_TABLE_HEADER))) 28967754Smsmith { 29082367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 29182367Smsmith "Cannot read table header at %p\n", TableHeader)); 29267754Smsmith return (AE_BAD_ADDRESS); 29367754Smsmith } 29467754Smsmith 29567754Smsmith 29667754Smsmith /* Ensure that the signature is 4 ASCII characters */ 29767754Smsmith 29867754Smsmith MOVE_UNALIGNED32_TO_32 (&Signature, &TableHeader->Signature); 29977424Smsmith if (!AcpiUtValidAcpiName (Signature)) 30067754Smsmith { 30182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 30282367Smsmith "Table signature at %p [%X] has invalid characters\n", 30367754Smsmith TableHeader, &Signature)); 30467754Smsmith 30577424Smsmith REPORT_WARNING (("Invalid table signature %4.4s found\n", &Signature)); 30667754Smsmith DUMP_BUFFER (TableHeader, sizeof (ACPI_TABLE_HEADER)); 30767754Smsmith return (AE_BAD_SIGNATURE); 30867754Smsmith } 30967754Smsmith 31067754Smsmith 31167754Smsmith /* Validate the table length */ 31267754Smsmith 31367754Smsmith if (TableHeader->Length < sizeof (ACPI_TABLE_HEADER)) 31467754Smsmith { 31582367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 31682367Smsmith "Invalid length in table header %p name %4.4s\n", 31767754Smsmith TableHeader, &Signature)); 31867754Smsmith 31967754Smsmith REPORT_WARNING (("Invalid table header length found\n")); 32067754Smsmith DUMP_BUFFER (TableHeader, sizeof (ACPI_TABLE_HEADER)); 32167754Smsmith return (AE_BAD_HEADER); 32267754Smsmith } 32367754Smsmith 32467754Smsmith return (AE_OK); 32567754Smsmith} 32667754Smsmith 32767754Smsmith 32867754Smsmith/******************************************************************************* 32967754Smsmith * 33067754Smsmith * FUNCTION: AcpiTbMapAcpiTable 33167754Smsmith * 33267754Smsmith * PARAMETERS: PhysicalAddress - Physical address of table to map 33367754Smsmith * *Size - Size of the table. If zero, the size 33467754Smsmith * from the table header is used. 33567754Smsmith * Actual size is returned here. 33667754Smsmith * **LogicalAddress - Logical address of mapped table 33767754Smsmith * 33867754Smsmith * RETURN: Logical address of the mapped table. 33967754Smsmith * 34067754Smsmith * DESCRIPTION: Maps the physical address of table into a logical address 34167754Smsmith * 34267754Smsmith ******************************************************************************/ 34367754Smsmith 34467754SmsmithACPI_STATUS 34567754SmsmithAcpiTbMapAcpiTable ( 34669450Smsmith ACPI_PHYSICAL_ADDRESS PhysicalAddress, 34767754Smsmith UINT32 *Size, 34878986Smsmith ACPI_TABLE_HEADER **LogicalAddress) 34967754Smsmith{ 35067754Smsmith ACPI_TABLE_HEADER *Table; 35167754Smsmith UINT32 TableSize = *Size; 35267754Smsmith ACPI_STATUS Status = AE_OK; 35367754Smsmith 35467754Smsmith 35582367Smsmith PROC_NAME ("TbMapAcpiTable"); 35682367Smsmith 35782367Smsmith 35867754Smsmith /* If size is zero, look at the table header to get the actual size */ 35967754Smsmith 36067754Smsmith if ((*Size) == 0) 36167754Smsmith { 36267754Smsmith /* Get the table header so we can extract the table length */ 36367754Smsmith 36467754Smsmith Status = AcpiOsMapMemory (PhysicalAddress, sizeof (ACPI_TABLE_HEADER), 36567754Smsmith (void **) &Table); 36667754Smsmith if (ACPI_FAILURE (Status)) 36767754Smsmith { 36867754Smsmith return (Status); 36967754Smsmith } 37067754Smsmith 37167754Smsmith /* Extract the full table length before we delete the mapping */ 37267754Smsmith 37367754Smsmith TableSize = Table->Length; 37467754Smsmith 37567754Smsmith /* 37667754Smsmith * Validate the header and delete the mapping. 37767754Smsmith * We will create a mapping for the full table below. 37867754Smsmith */ 37967754Smsmith Status = AcpiTbValidateTableHeader (Table); 38067754Smsmith 38167754Smsmith /* Always unmap the memory for the header */ 38267754Smsmith 38367754Smsmith AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 38467754Smsmith 38567754Smsmith /* Exit if header invalid */ 38667754Smsmith 38767754Smsmith if (ACPI_FAILURE (Status)) 38867754Smsmith { 38967754Smsmith return (Status); 39067754Smsmith } 39167754Smsmith } 39267754Smsmith 39367754Smsmith 39467754Smsmith /* Map the physical memory for the correct length */ 39567754Smsmith 39667754Smsmith Status = AcpiOsMapMemory (PhysicalAddress, TableSize, (void **) &Table); 39767754Smsmith if (ACPI_FAILURE (Status)) 39867754Smsmith { 39967754Smsmith return (Status); 40067754Smsmith } 40167754Smsmith 40282367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 40382367Smsmith "Mapped memory for ACPI table, length=%d(%X) at %p\n", 40467754Smsmith TableSize, TableSize, Table)); 40567754Smsmith 40667754Smsmith *Size = TableSize; 40767754Smsmith *LogicalAddress = Table; 40867754Smsmith 40967754Smsmith return (Status); 41067754Smsmith} 41167754Smsmith 41267754Smsmith 41367754Smsmith/******************************************************************************* 41467754Smsmith * 41567754Smsmith * FUNCTION: AcpiTbVerifyTableChecksum 41667754Smsmith * 41767754Smsmith * PARAMETERS: *TableHeader - ACPI table to verify 41867754Smsmith * 41967754Smsmith * RETURN: 8 bit checksum of table 42067754Smsmith * 42167754Smsmith * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct 42267754Smsmith * table should have a checksum of 0. 42367754Smsmith * 42467754Smsmith ******************************************************************************/ 42567754Smsmith 42667754SmsmithACPI_STATUS 42767754SmsmithAcpiTbVerifyTableChecksum ( 42867754Smsmith ACPI_TABLE_HEADER *TableHeader) 42967754Smsmith{ 43067754Smsmith UINT8 Checksum; 43167754Smsmith ACPI_STATUS Status = AE_OK; 43267754Smsmith 43367754Smsmith 43467754Smsmith FUNCTION_TRACE ("TbVerifyTableChecksum"); 43567754Smsmith 43667754Smsmith 43767754Smsmith /* Compute the checksum on the table */ 43867754Smsmith 43967754Smsmith Checksum = AcpiTbChecksum (TableHeader, TableHeader->Length); 44067754Smsmith 44167754Smsmith /* Return the appropriate exception */ 44267754Smsmith 44367754Smsmith if (Checksum) 44467754Smsmith { 44567754Smsmith REPORT_WARNING (("Invalid checksum (%X) in table %4.4s\n", 44667754Smsmith Checksum, &TableHeader->Signature)); 44767754Smsmith 44867754Smsmith Status = AE_BAD_CHECKSUM; 44967754Smsmith } 45067754Smsmith 45167754Smsmith 45267754Smsmith return_ACPI_STATUS (Status); 45367754Smsmith} 45467754Smsmith 45567754Smsmith 45667754Smsmith/******************************************************************************* 45767754Smsmith * 45867754Smsmith * FUNCTION: AcpiTbChecksum 45967754Smsmith * 46067754Smsmith * PARAMETERS: Buffer - Buffer to checksum 46167754Smsmith * Length - Size of the buffer 46267754Smsmith * 46367754Smsmith * RETURNS 8 bit checksum of buffer 46467754Smsmith * 46567754Smsmith * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it. 46667754Smsmith * 46767754Smsmith ******************************************************************************/ 46867754Smsmith 46967754SmsmithUINT8 47067754SmsmithAcpiTbChecksum ( 47167754Smsmith void *Buffer, 47267754Smsmith UINT32 Length) 47367754Smsmith{ 47467754Smsmith UINT8 *limit; 47567754Smsmith UINT8 *rover; 47667754Smsmith UINT8 sum = 0; 47767754Smsmith 47867754Smsmith 47967754Smsmith if (Buffer && Length) 48067754Smsmith { 48167754Smsmith /* Buffer and Length are valid */ 48267754Smsmith 48367754Smsmith limit = (UINT8 *) Buffer + Length; 48467754Smsmith 48567754Smsmith for (rover = Buffer; rover < limit; rover++) 48667754Smsmith { 48767754Smsmith sum = (UINT8) (sum + *rover); 48867754Smsmith } 48967754Smsmith } 49067754Smsmith 49167754Smsmith return (sum); 49267754Smsmith} 49367754Smsmith 49467754Smsmith 495