tbutils.c revision 71867
159191Skris/****************************************************************************** 2280304Sjkim * 3280304Sjkim * Module Name: tbutils - Table manipulation utilities 4160814Ssimon * $Revision: 33 $ 559191Skris * 659191Skris *****************************************************************************/ 7160814Ssimon 859191Skris/****************************************************************************** 959191Skris * 1059191Skris * 1. Copyright Notice 1159191Skris * 1259191Skris * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1359191Skris * All rights reserved. 14280304Sjkim * 1559191Skris * 2. License 1659191Skris * 1759191Skris * 2.1. This is your license from Intel Corp. under its intellectual property 1859191Skris * rights. You may have additional license terms from the party that provided 1959191Skris * you this software, covering your right to use that party's intellectual 2059191Skris * property rights. 2159191Skris * 2259191Skris * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2359191Skris * copy of the source code appearing in this file ("Covered Code") an 2459191Skris * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2559191Skris * base code distributed originally by Intel ("Original Intel Code") to copy, 2659191Skris * make derivatives, distribute, use and display any portion of the Covered 2759191Skris * Code in any form, with the right to sublicense such rights; and 2859191Skris * 2959191Skris * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3059191Skris * license (with the right to sublicense), under only those claims of Intel 3159191Skris * patents that are infringed by the Original Intel Code, to make, use, sell, 3259191Skris * offer to sell, and import the Covered Code and derivative works thereof 3359191Skris * solely to the minimum extent necessary to exercise the above copyright 3459191Skris * license, and in no event shall the patent license extend to any additions 3559191Skris * to or modifications of the Original Intel Code. No other license or right 3659191Skris * is granted directly or by implication, estoppel or otherwise; 3759191Skris * 3859191Skris * The above copyright and patent license is granted only if the following 3959191Skris * conditions are met: 4059191Skris * 4159191Skris * 3. Conditions 4259191Skris * 4359191Skris * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4459191Skris * Redistribution of source code of any substantial portion of the Covered 4559191Skris * Code or modification with rights to further distribute source must include 4659191Skris * the above Copyright Notice, the above License, this list of Conditions, 4759191Skris * and the following Disclaimer and Export Compliance provision. In addition, 4859191Skris * Licensee must cause all Covered Code to which Licensee contributes to 4959191Skris * contain a file documenting the changes Licensee made to create that Covered 5059191Skris * Code and the date of any change. Licensee must include in that file the 5159191Skris * documentation of any changes made by any predecessor Licensee. Licensee 5259191Skris * must include a prominent statement that the modification is derived, 5359191Skris * directly or indirectly, from Original Intel Code. 5459191Skris * 5559191Skris * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5659191Skris * Redistribution of source code of any substantial portion of the Covered 5759191Skris * Code or modification without rights to further distribute source must 5859191Skris * include the following Disclaimer and Export Compliance provision in the 5959191Skris * documentation and/or other materials provided with distribution. In 6059191Skris * addition, Licensee may not authorize further sublicense of source of any 6159191Skris * portion of the Covered Code, and must include terms to the effect that the 6259191Skris * license from Licensee to its licensee is limited to the intellectual 6359191Skris * property embodied in the software Licensee provides to its licensee, and 6459191Skris * not to intellectual property embodied in modifications its licensee may 6559191Skris * make. 6659191Skris * 6759191Skris * 3.3. Redistribution of Executable. Redistribution in executable form of any 68160814Ssimon * substantial portion of the Covered Code or modification must reproduce the 69160814Ssimon * above Copyright Notice, and the following Disclaimer and Export Compliance 7059191Skris * provision in the documentation and/or other materials provided with the 7159191Skris * distribution. 7259191Skris * 7359191Skris * 3.4. Intel retains all right, title, and interest in and to the Original 74160814Ssimon * Intel Code. 7559191Skris * 76280304Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77280304Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 78280304Sjkim * other dealings in products derived from or relating to the Covered Code 79280304Sjkim * without prior written authorization from Intel. 80280304Sjkim * 81280304Sjkim * 4. Disclaimer and Export Compliance 82280304Sjkim * 83280304Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84280304Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8559191Skris * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8659191Skris * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8759191Skris * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8859191Skris * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89280304Sjkim * PARTICULAR PURPOSE. 90280304Sjkim * 91280304Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92280304Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93280304Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94280304Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95280304Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96280304Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97280304Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98280304Sjkim * LIMITED REMEDY. 99280304Sjkim * 100280304Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 101280304Sjkim * software or system incorporating such software without first obtaining any 102280304Sjkim * required license or other approval from the U. S. Department of Commerce or 103280304Sjkim * any other agency or department of the United States Government. In the 104280304Sjkim * event Licensee exports any such software from the United States or 105280304Sjkim * re-exports any such software from a foreign destination, Licensee shall 106280304Sjkim * ensure that the distribution and export/re-export of the software is in 107280304Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 108280304Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109280304Sjkim * any of its subsidiaries will export/re-export any technical data, process, 110280304Sjkim * software, or service, directly or indirectly, to any country for which the 111280304Sjkim * United States government or any agency thereof requires an export license, 112280304Sjkim * other governmental approval, or letter of assurance, without first obtaining 113280304Sjkim * such license, approval or letter. 114280304Sjkim * 115280304Sjkim *****************************************************************************/ 116280304Sjkim 117111147Snectar#define __TBUTILS_C__ 118280304Sjkim 119111147Snectar#include "acpi.h" 120109998Smarkm#include "actables.h" 121280304Sjkim#include "acinterp.h" 122160814Ssimon 123280304Sjkim 124280304Sjkim#define _COMPONENT TABLE_MANAGER 12559191Skris MODULE_NAME ("tbutils") 126280304Sjkim 127109998Smarkm 128280304Sjkim/******************************************************************************* 129280304Sjkim * 130280304Sjkim * FUNCTION: AcpiTbHandleToObject 131280304Sjkim * 132109998Smarkm * PARAMETERS: TableId - Id for which the function is searching 133280304Sjkim * TableDesc - Pointer to return the matching table 134280304Sjkim * descriptor. 135109998Smarkm * 136280304Sjkim * RETURN: Search the tables to find one with a matching TableId and 137280304Sjkim * return a pointer to that table descriptor. 138280304Sjkim * 139280304Sjkim ******************************************************************************/ 140280304Sjkim 141280304SjkimACPI_STATUS 142280304SjkimAcpiTbHandleToObject ( 143280304Sjkim UINT16 TableId, 144280304Sjkim ACPI_TABLE_DESC **TableDesc) 145280304Sjkim{ 146280304Sjkim UINT32 i; 147280304Sjkim ACPI_TABLE_DESC *ListHead; 148280304Sjkim 149109998Smarkm 150280304Sjkim for (i = 0; i < ACPI_TABLE_MAX; i++) 151280304Sjkim { 152280304Sjkim ListHead = &AcpiGbl_AcpiTables[i]; 153280304Sjkim do 15459191Skris { 155194206Ssimon if (ListHead->TableId == TableId) 156280304Sjkim { 157280304Sjkim *TableDesc = ListHead; 158194206Ssimon return (AE_OK); 159109998Smarkm } 160280304Sjkim 161280304Sjkim ListHead = ListHead->Next; 162280304Sjkim 163280304Sjkim } while (ListHead != &AcpiGbl_AcpiTables[i]); 164280304Sjkim } 165280304Sjkim 16659191Skris 167109998Smarkm DEBUG_PRINT (ACPI_ERROR, ("TableId=%X does not exist\n", TableId)); 168280304Sjkim return (AE_BAD_PARAMETER); 169280304Sjkim} 170280304Sjkim 171280304Sjkim 172280304Sjkim/******************************************************************************* 173280304Sjkim * 174109998Smarkm * FUNCTION: AcpiTbSystemTablePointer 175162911Ssimon * 176280304Sjkim * PARAMETERS: *Where - Pointer to be examined 177280304Sjkim * 178280304Sjkim * RETURN: TRUE if Where is within the AML stream (in one of the ACPI 179280304Sjkim * system tables such as the DSDT or an SSDT.) 180280304Sjkim * FALSE otherwise 181280304Sjkim * 182162911Ssimon ******************************************************************************/ 183280304Sjkim 184280304SjkimBOOLEAN 185280304SjkimAcpiTbSystemTablePointer ( 186280304Sjkim void *Where) 187280304Sjkim{ 188280304Sjkim UINT32 i; 189280304Sjkim ACPI_TABLE_DESC *TableDesc; 190280304Sjkim ACPI_TABLE_HEADER *Table; 191280304Sjkim 192280304Sjkim 193280304Sjkim /* No function trace, called too often! */ 194280304Sjkim 195280304Sjkim 196280304Sjkim /* Ignore null pointer */ 197280304Sjkim 198280304Sjkim if (!Where) 199280304Sjkim { 200280304Sjkim return (FALSE); 201280304Sjkim } 202280304Sjkim 203280304Sjkim 204280304Sjkim /* Check for a pointer within the DSDT */ 205280304Sjkim 206280304Sjkim if ((AcpiGbl_DSDT) && 207280304Sjkim (IS_IN_ACPI_TABLE (Where, AcpiGbl_DSDT))) 208280304Sjkim { 209280304Sjkim return (TRUE); 210280304Sjkim } 211280304Sjkim 212280304Sjkim 213280304Sjkim /* Check each of the loaded SSDTs (if any)*/ 214280304Sjkim 215280304Sjkim TableDesc = &AcpiGbl_AcpiTables[ACPI_TABLE_SSDT]; 216280304Sjkim 217280304Sjkim for (i = 0; i < AcpiGbl_AcpiTables[ACPI_TABLE_SSDT].Count; i++) 218280304Sjkim { 219280304Sjkim Table = TableDesc->Pointer; 220111147Snectar 221280304Sjkim if (IS_IN_ACPI_TABLE (Where, Table)) 222280304Sjkim { 223280304Sjkim return (TRUE); 224280304Sjkim } 225280304Sjkim 226111147Snectar TableDesc = TableDesc->Next; 227280304Sjkim } 228280304Sjkim 229280304Sjkim 230280304Sjkim /* Check each of the loaded PSDTs (if any)*/ 231280304Sjkim 232280304Sjkim TableDesc = &AcpiGbl_AcpiTables[ACPI_TABLE_PSDT]; 233280304Sjkim 234280304Sjkim for (i = 0; i < AcpiGbl_AcpiTables[ACPI_TABLE_PSDT].Count; i++) 235280304Sjkim { 236280304Sjkim Table = TableDesc->Pointer; 237280304Sjkim 238280304Sjkim if (IS_IN_ACPI_TABLE (Where, Table)) 239280304Sjkim { 240280304Sjkim return (TRUE); 241280304Sjkim } 242280304Sjkim 243280304Sjkim TableDesc = TableDesc->Next; 244280304Sjkim } 245280304Sjkim 246280304Sjkim 247238405Sjkim /* Pointer does not point into any system table */ 248280304Sjkim 249280304Sjkim return (FALSE); 250280304Sjkim} 251280304Sjkim 252280304Sjkim 253280304Sjkim/******************************************************************************* 254280304Sjkim * 255280304Sjkim * FUNCTION: AcpiTbValidateTableHeader 256280304Sjkim * 257280304Sjkim * PARAMETERS: TableHeader - Logical pointer to the table 258280304Sjkim * 259280304Sjkim * RETURN: Status 260280304Sjkim * 261280304Sjkim * DESCRIPTION: Check an ACPI table header for validity 262280304Sjkim * 263280304Sjkim * NOTE: Table pointers are validated as follows: 264280304Sjkim * 1) Table pointer must point to valid physical memory 265280304Sjkim * 2) Signature must be 4 ASCII chars, even if we don't recognize the 266280304Sjkim * name 267280304Sjkim * 3) Table must be readable for length specified in the header 268280304Sjkim * 4) Table checksum must be valid (with the exception of the FACS 269280304Sjkim * which has no checksum for some odd reason) 270280304Sjkim * 271280304Sjkim ******************************************************************************/ 272280304Sjkim 273280304SjkimACPI_STATUS 274280304SjkimAcpiTbValidateTableHeader ( 275280304Sjkim ACPI_TABLE_HEADER *TableHeader) 276280304Sjkim{ 277280304Sjkim ACPI_NAME Signature; 278280304Sjkim 279280304Sjkim 280280304Sjkim /* Verify that this is a valid address */ 281280304Sjkim 282280304Sjkim if (!AcpiOsReadable (TableHeader, sizeof (ACPI_TABLE_HEADER))) 283280304Sjkim { 284280304Sjkim DEBUG_PRINT (ACPI_ERROR, 285280304Sjkim ("Cannot read table header at %p\n", TableHeader)); 286280304Sjkim return (AE_BAD_ADDRESS); 287280304Sjkim } 288280304Sjkim 289280304Sjkim 290280304Sjkim /* Ensure that the signature is 4 ASCII characters */ 291280304Sjkim 292280304Sjkim MOVE_UNALIGNED32_TO_32 (&Signature, &TableHeader->Signature); 293280304Sjkim if (!AcpiCmValidAcpiName (Signature)) 294280304Sjkim { 295280304Sjkim DEBUG_PRINT (ACPI_ERROR, 296280304Sjkim ("Table signature at %p [%X] has invalid characters\n", 297280304Sjkim TableHeader, &Signature)); 298280304Sjkim 299280304Sjkim REPORT_WARNING (("Invalid table signature found\n")); 300280304Sjkim DUMP_BUFFER (TableHeader, sizeof (ACPI_TABLE_HEADER)); 301280304Sjkim return (AE_BAD_SIGNATURE); 302280304Sjkim } 303280304Sjkim 304280304Sjkim 305280304Sjkim /* Validate the table length */ 306280304Sjkim 307280304Sjkim if (TableHeader->Length < sizeof (ACPI_TABLE_HEADER)) 308280304Sjkim { 309280304Sjkim DEBUG_PRINT (ACPI_ERROR, 310280304Sjkim ("Invalid length in table header %p name %4.4s\n", 311280304Sjkim TableHeader, &Signature)); 312280304Sjkim 313280304Sjkim REPORT_WARNING (("Invalid table header length found\n")); 314280304Sjkim DUMP_BUFFER (TableHeader, sizeof (ACPI_TABLE_HEADER)); 315280304Sjkim return (AE_BAD_HEADER); 316280304Sjkim } 317280304Sjkim 318280304Sjkim return (AE_OK); 319280304Sjkim} 320280304Sjkim 321280304Sjkim 322280304Sjkim/******************************************************************************* 323280304Sjkim * 324280304Sjkim * FUNCTION: AcpiTbMapAcpiTable 325280304Sjkim * 326280304Sjkim * PARAMETERS: PhysicalAddress - Physical address of table to map 327280304Sjkim * *Size - Size of the table. If zero, the size 328280304Sjkim * from the table header is used. 329280304Sjkim * Actual size is returned here. 330280304Sjkim * **LogicalAddress - Logical address of mapped table 331280304Sjkim * 33259191Skris * RETURN: Logical address of the mapped table. 333280304Sjkim * 334280304Sjkim * DESCRIPTION: Maps the physical address of table into a logical address 335280304Sjkim * 336280304Sjkim ******************************************************************************/ 337160814Ssimon 338280304SjkimACPI_STATUS 339280304SjkimAcpiTbMapAcpiTable ( 340280304Sjkim ACPI_PHYSICAL_ADDRESS PhysicalAddress, 341280304Sjkim UINT32 *Size, 342280304Sjkim void **LogicalAddress) 343280304Sjkim{ 344280304Sjkim ACPI_TABLE_HEADER *Table; 345280304Sjkim UINT32 TableSize = *Size; 346280304Sjkim ACPI_STATUS Status = AE_OK; 347280304Sjkim 348280304Sjkim 349280304Sjkim /* If size is zero, look at the table header to get the actual size */ 350280304Sjkim 351280304Sjkim if ((*Size) == 0) 352280304Sjkim { 353280304Sjkim /* Get the table header so we can extract the table length */ 354280304Sjkim 355280304Sjkim Status = AcpiOsMapMemory (PhysicalAddress, sizeof (ACPI_TABLE_HEADER), 356280304Sjkim (void **) &Table); 357280304Sjkim if (ACPI_FAILURE (Status)) 358280304Sjkim { 359280304Sjkim return (Status); 360280304Sjkim } 361280304Sjkim 362280304Sjkim /* Extract the full table length before we delete the mapping */ 363280304Sjkim 364280304Sjkim TableSize = Table->Length; 365280304Sjkim 366280304Sjkim /* 367280304Sjkim * Validate the header and delete the mapping. 368280304Sjkim * We will create a mapping for the full table below. 369280304Sjkim */ 370280304Sjkim 371280304Sjkim Status = AcpiTbValidateTableHeader (Table); 372280304Sjkim 373280304Sjkim /* Always unmap the memory for the header */ 374280304Sjkim 37559191Skris AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 376280304Sjkim 377280304Sjkim /* Exit if header invalid */ 378280304Sjkim 379280304Sjkim if (ACPI_FAILURE (Status)) 380280304Sjkim { 381280304Sjkim return (Status); 382280304Sjkim } 383280304Sjkim } 384280304Sjkim 385109998Smarkm 386280304Sjkim /* Map the physical memory for the correct length */ 387280304Sjkim 38859191Skris Status = AcpiOsMapMemory (PhysicalAddress, TableSize, (void **) &Table); 389194206Ssimon if (ACPI_FAILURE (Status)) 390280304Sjkim { 391194206Ssimon return (Status); 392109998Smarkm } 393280304Sjkim 394280304Sjkim DEBUG_PRINT (ACPI_INFO, 395280304Sjkim ("Mapped memory for ACPI table, length=%d(%X) at %p\n", 39659191Skris TableSize, TableSize, Table)); 397109998Smarkm 398280304Sjkim *Size = TableSize; 399280304Sjkim *LogicalAddress = Table; 400280304Sjkim 401109998Smarkm return (Status); 402162911Ssimon} 403280304Sjkim 404280304Sjkim 405280304Sjkim/******************************************************************************* 406162911Ssimon * 407280304Sjkim * FUNCTION: AcpiTbVerifyTableChecksum 408280304Sjkim * 409280304Sjkim * PARAMETERS: *TableHeader - ACPI table to verify 410280304Sjkim * 411280304Sjkim * RETURN: 8 bit checksum of table 412280304Sjkim * 413280304Sjkim * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct 414280304Sjkim * table should have a checksum of 0. 415280304Sjkim * 416280304Sjkim ******************************************************************************/ 417280304Sjkim 418280304SjkimACPI_STATUS 419280304SjkimAcpiTbVerifyTableChecksum ( 420280304Sjkim ACPI_TABLE_HEADER *TableHeader) 421280304Sjkim{ 422280304Sjkim UINT8 Checksum; 423280304Sjkim ACPI_STATUS Status = AE_OK; 424280304Sjkim 425280304Sjkim 426280304Sjkim FUNCTION_TRACE ("TbVerifyTableChecksum"); 427280304Sjkim 428280304Sjkim 429280304Sjkim /* Compute the checksum on the table */ 430280304Sjkim 431280304Sjkim Checksum = AcpiTbChecksum (TableHeader, TableHeader->Length); 432280304Sjkim 433280304Sjkim /* Return the appropriate exception */ 434280304Sjkim 435280304Sjkim if (Checksum) 436280304Sjkim { 437280304Sjkim REPORT_WARNING (("Invalid checksum (%X) in table %4.4s\n", 438280304Sjkim Checksum, &TableHeader->Signature)); 439280304Sjkim 440280304Sjkim Status = AE_BAD_CHECKSUM; 441280304Sjkim } 442280304Sjkim 443280304Sjkim 444280304Sjkim return_ACPI_STATUS (Status); 445284285Sjkim} 446284285Sjkim 447280304Sjkim 448280304Sjkim/******************************************************************************* 449280304Sjkim * 450111147Snectar * FUNCTION: AcpiTbChecksum 451280304Sjkim * 452280304Sjkim * PARAMETERS: Buffer - Buffer to checksum 453111147Snectar * Length - Size of the buffer 454280304Sjkim * 455280304Sjkim * RETURNS 8 bit checksum of buffer 456280304Sjkim * 457280304Sjkim * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it. 458280304Sjkim * 459280304Sjkim ******************************************************************************/ 460280304Sjkim 461280304SjkimUINT8 462280304SjkimAcpiTbChecksum ( 463280304Sjkim void *Buffer, 464111147Snectar UINT32 Length) 465280304Sjkim{ 466111147Snectar UINT8 *limit; 467109998Smarkm UINT8 *rover; 468280304Sjkim UINT8 sum = 0; 469280304Sjkim 470280304Sjkim 471280304Sjkim if (Buffer && Length) 47259191Skris { 473280304Sjkim /* Buffer and Length are valid */ 474280304Sjkim 475280304Sjkim limit = (UINT8 *) Buffer + Length; 476280304Sjkim 477280304Sjkim for (rover = Buffer; rover < limit; rover++) 478280304Sjkim { 47959191Skris sum = (UINT8) (sum + *rover); 480280304Sjkim } 48159191Skris } 482280304Sjkim 483280304Sjkim return (sum); 48459191Skris} 485280304Sjkim 486280304Sjkim 487280304Sjkim