tbutils.c revision 193341
167754Smsmith/****************************************************************************** 267754Smsmith * 3167802Sjkim * Module Name: tbutils - table utilities 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 767754Smsmith/****************************************************************************** 867754Smsmith * 967754Smsmith * 1. Copyright Notice 1067754Smsmith * 11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 1467754Smsmith * 2. License 1567754Smsmith * 1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1767754Smsmith * rights. You may have additional license terms from the party that provided 1867754Smsmith * you this software, covering your right to use that party's intellectual 1967754Smsmith * property rights. 2067754Smsmith * 2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2667754Smsmith * Code in any form, with the right to sublicense such rights; and 2767754Smsmith * 2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2967754Smsmith * license (with the right to sublicense), under only those claims of Intel 3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3367754Smsmith * license, and in no event shall the patent license extend to any additions 3467754Smsmith * to or modifications of the Original Intel Code. No other license or right 3567754Smsmith * is granted directly or by implication, estoppel or otherwise; 3667754Smsmith * 3767754Smsmith * The above copyright and patent license is granted only if the following 3867754Smsmith * conditions are met: 3967754Smsmith * 4067754Smsmith * 3. Conditions 4167754Smsmith * 4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4367754Smsmith * Redistribution of source code of any substantial portion of the Covered 4467754Smsmith * Code or modification with rights to further distribute source must include 4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4667754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered 4967754Smsmith * Code and the date of any change. Licensee must include in that file the 5067754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5167754Smsmith * must include a prominent statement that the modification is derived, 5267754Smsmith * directly or indirectly, from Original Intel Code. 5367754Smsmith * 5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5567754Smsmith * Redistribution of source code of any substantial portion of the Covered 5667754Smsmith * Code or modification without rights to further distribute source must 5767754Smsmith * include the following Disclaimer and Export Compliance provision in the 5867754Smsmith * documentation and/or other materials provided with distribution. In 5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6167754Smsmith * license from Licensee to its licensee is limited to the intellectual 6267754Smsmith * property embodied in the software Licensee provides to its licensee, and 6367754Smsmith * not to intellectual property embodied in modifications its licensee may 6467754Smsmith * make. 6567754Smsmith * 6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 6967754Smsmith * provision in the documentation and/or other materials provided with the 7067754Smsmith * distribution. 7167754Smsmith * 7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7367754Smsmith * Intel Code. 7467754Smsmith * 7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7767754Smsmith * other dealings in products derived from or relating to the Covered Code 7867754Smsmith * without prior written authorization from Intel. 7967754Smsmith * 8067754Smsmith * 4. Disclaimer and Export Compliance 8167754Smsmith * 8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8367754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8867754Smsmith * PARTICULAR PURPOSE. 8967754Smsmith * 9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9767754Smsmith * LIMITED REMEDY. 9867754Smsmith * 9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10067754Smsmith * software or system incorporating such software without first obtaining any 10167754Smsmith * required license or other approval from the U. S. Department of Commerce or 10267754Smsmith * any other agency or department of the United States Government. In the 10367754Smsmith * event Licensee exports any such software from the United States or 10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10567754Smsmith * ensure that the distribution and export/re-export of the software is in 10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 10967754Smsmith * software, or service, directly or indirectly, to any country for which the 11067754Smsmith * United States government or any agency thereof requires an export license, 11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11267754Smsmith * such license, approval or letter. 11367754Smsmith * 11467754Smsmith *****************************************************************************/ 11567754Smsmith 11667754Smsmith#define __TBUTILS_C__ 11767754Smsmith 118193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 119193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 120193341Sjkim#include <contrib/dev/acpica/include/actables.h> 12167754Smsmith 12277424Smsmith#define _COMPONENT ACPI_TABLES 12391116Smsmith ACPI_MODULE_NAME ("tbutils") 12467754Smsmith 125151937Sjkim/* Local prototypes */ 12667754Smsmith 127167802Sjkimstatic ACPI_PHYSICAL_ADDRESS 128167802SjkimAcpiTbGetRootTableEntry ( 129167802Sjkim UINT8 *TableEntry, 130193267Sjkim UINT32 TableEntrySize); 131151937Sjkim 132151937Sjkim 13367754Smsmith/******************************************************************************* 13467754Smsmith * 135193267Sjkim * FUNCTION: AcpiTbInitializeFacs 136193267Sjkim * 137193267Sjkim * PARAMETERS: None 138193267Sjkim * 139193267Sjkim * RETURN: Status 140193267Sjkim * 141193267Sjkim * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global 142193267Sjkim * for accessing the Global Lock and Firmware Waking Vector 143193267Sjkim * 144193267Sjkim ******************************************************************************/ 145193267Sjkim 146193267SjkimACPI_STATUS 147193267SjkimAcpiTbInitializeFacs ( 148193267Sjkim void) 149193267Sjkim{ 150193267Sjkim ACPI_STATUS Status; 151193267Sjkim 152193267Sjkim 153193267Sjkim Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, 154193267Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS)); 155193267Sjkim return (Status); 156193267Sjkim} 157193267Sjkim 158193267Sjkim 159193267Sjkim/******************************************************************************* 160193267Sjkim * 161167802Sjkim * FUNCTION: AcpiTbTablesLoaded 16267754Smsmith * 163167802Sjkim * PARAMETERS: None 16467754Smsmith * 165167802Sjkim * RETURN: TRUE if required ACPI tables are loaded 16667754Smsmith * 167167802Sjkim * DESCRIPTION: Determine if the minimum required ACPI tables are present 168167802Sjkim * (FADT, FACS, DSDT) 169151937Sjkim * 17067754Smsmith ******************************************************************************/ 17167754Smsmith 172167802SjkimBOOLEAN 173167802SjkimAcpiTbTablesLoaded ( 174167802Sjkim void) 17567754Smsmith{ 17667754Smsmith 177167802Sjkim if (AcpiGbl_RootTableList.Count >= 3) 178167802Sjkim { 179167802Sjkim return (TRUE); 180167802Sjkim } 18183174Smsmith 182167802Sjkim return (FALSE); 183167802Sjkim} 18467754Smsmith 18582367Smsmith 186167802Sjkim/******************************************************************************* 187167802Sjkim * 188167802Sjkim * FUNCTION: AcpiTbPrintTableHeader 189167802Sjkim * 190167802Sjkim * PARAMETERS: Address - Table physical address 191167802Sjkim * Header - Table header 192167802Sjkim * 193167802Sjkim * RETURN: None 194167802Sjkim * 195167802Sjkim * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. 196167802Sjkim * 197167802Sjkim ******************************************************************************/ 198151937Sjkim 199167802Sjkimvoid 200167802SjkimAcpiTbPrintTableHeader ( 201167802Sjkim ACPI_PHYSICAL_ADDRESS Address, 202167802Sjkim ACPI_TABLE_HEADER *Header) 203167802Sjkim{ 204151937Sjkim 205193267Sjkim /* 206193267Sjkim * The reason that the Address is cast to a void pointer is so that we 207193267Sjkim * can use %p which will work properly on both 32-bit and 64-bit hosts. 208193267Sjkim */ 209167802Sjkim if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS)) 210167802Sjkim { 211193267Sjkim /* FACS only has signature and length fields */ 212151937Sjkim 213193267Sjkim ACPI_INFO ((AE_INFO, "%4.4s %p %05X", 214193267Sjkim Header->Signature, ACPI_CAST_PTR (void, Address), 215193267Sjkim Header->Length)); 216167802Sjkim } 217167802Sjkim else if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_RSDP)) 21867754Smsmith { 219167802Sjkim /* RSDP has no common fields */ 22067754Smsmith 221193267Sjkim ACPI_INFO ((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", 222167802Sjkim ACPI_CAST_PTR (void, Address), 223167802Sjkim (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ? 224167802Sjkim ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20, 225167802Sjkim ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision, 226167802Sjkim ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId)); 227167802Sjkim } 228167802Sjkim else 229167802Sjkim { 230167802Sjkim /* Standard ACPI table with full common header */ 231151937Sjkim 232167802Sjkim ACPI_INFO ((AE_INFO, 233193267Sjkim "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", 234167802Sjkim Header->Signature, ACPI_CAST_PTR (void, Address), 235167802Sjkim Header->Length, Header->Revision, Header->OemId, 236167802Sjkim Header->OemTableId, Header->OemRevision, Header->AslCompilerId, 237167802Sjkim Header->AslCompilerRevision)); 23867754Smsmith } 23967754Smsmith} 24067754Smsmith 24167754Smsmith 24267754Smsmith/******************************************************************************* 24367754Smsmith * 244167802Sjkim * FUNCTION: AcpiTbValidateChecksum 24567754Smsmith * 246167802Sjkim * PARAMETERS: Table - ACPI table to verify 247167802Sjkim * Length - Length of entire table 24867754Smsmith * 24967754Smsmith * RETURN: Status 25067754Smsmith * 251167802Sjkim * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns 252167802Sjkim * exception on bad checksum. 25367754Smsmith * 25467754Smsmith ******************************************************************************/ 25567754Smsmith 25667754SmsmithACPI_STATUS 257167802SjkimAcpiTbVerifyChecksum ( 258167802Sjkim ACPI_TABLE_HEADER *Table, 259167802Sjkim UINT32 Length) 26067754Smsmith{ 261167802Sjkim UINT8 Checksum; 26267754Smsmith 26367754Smsmith 264167802Sjkim /* Compute the checksum on the table */ 26577424Smsmith 266167802Sjkim Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Length); 26777424Smsmith 268167802Sjkim /* Checksum ok? (should be zero) */ 26967754Smsmith 270167802Sjkim if (Checksum) 27167754Smsmith { 272167802Sjkim ACPI_WARNING ((AE_INFO, 273193267Sjkim "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X", 274193267Sjkim Table->Signature, Table->Checksum, 275193267Sjkim (UINT8) (Table->Checksum - Checksum))); 276151937Sjkim 277167802Sjkim#if (ACPI_CHECKSUM_ABORT) 278167802Sjkim return (AE_BAD_CHECKSUM); 279167802Sjkim#endif 28067754Smsmith } 28167754Smsmith 282167802Sjkim return (AE_OK); 283167802Sjkim} 28467754Smsmith 28567754Smsmith 286167802Sjkim/******************************************************************************* 287167802Sjkim * 288167802Sjkim * FUNCTION: AcpiTbChecksum 289167802Sjkim * 290167802Sjkim * PARAMETERS: Buffer - Pointer to memory region to be checked 291167802Sjkim * Length - Length of this memory region 292167802Sjkim * 293167802Sjkim * RETURN: Checksum (UINT8) 294167802Sjkim * 295167802Sjkim * DESCRIPTION: Calculates circular checksum of memory region. 296167802Sjkim * 297167802Sjkim ******************************************************************************/ 298151937Sjkim 299167802SjkimUINT8 300167802SjkimAcpiTbChecksum ( 301167802Sjkim UINT8 *Buffer, 302193267Sjkim UINT32 Length) 303167802Sjkim{ 304167802Sjkim UINT8 Sum = 0; 305167802Sjkim UINT8 *End = Buffer + Length; 30667754Smsmith 30767754Smsmith 308167802Sjkim while (Buffer < End) 30967754Smsmith { 310167802Sjkim Sum = (UINT8) (Sum + *(Buffer++)); 31167754Smsmith } 31267754Smsmith 313167802Sjkim return Sum; 31467754Smsmith} 31567754Smsmith 31667754Smsmith 31767754Smsmith/******************************************************************************* 31867754Smsmith * 319167802Sjkim * FUNCTION: AcpiTbInstallTable 32067754Smsmith * 321167802Sjkim * PARAMETERS: Address - Physical address of DSDT or FACS 322167802Sjkim * Signature - Table signature, NULL if no need to 323167802Sjkim * match 324167802Sjkim * TableIndex - Index into root table array 32567754Smsmith * 326167802Sjkim * RETURN: None 32767754Smsmith * 328193267Sjkim * DESCRIPTION: Install an ACPI table into the global data structure. The 329193267Sjkim * table override mechanism is implemented here to allow the host 330193267Sjkim * OS to replace any table before it is installed in the root 331193267Sjkim * table array. 33267754Smsmith * 33367754Smsmith ******************************************************************************/ 33467754Smsmith 335167802Sjkimvoid 336167802SjkimAcpiTbInstallTable ( 337167802Sjkim ACPI_PHYSICAL_ADDRESS Address, 338167802Sjkim char *Signature, 339193267Sjkim UINT32 TableIndex) 34067754Smsmith{ 341193267Sjkim UINT8 Flags; 342193267Sjkim ACPI_STATUS Status; 343193267Sjkim ACPI_TABLE_HEADER *TableToInstall; 344193267Sjkim ACPI_TABLE_HEADER *MappedTable; 345193267Sjkim ACPI_TABLE_HEADER *OverrideTable = NULL; 34667754Smsmith 34767754Smsmith 348167802Sjkim if (!Address) 349167802Sjkim { 350167802Sjkim ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", 351167802Sjkim Signature)); 352167802Sjkim return; 353167802Sjkim } 35467754Smsmith 355167802Sjkim /* Map just the table header */ 35667754Smsmith 357193267Sjkim MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 358193267Sjkim if (!MappedTable) 359167802Sjkim { 360167802Sjkim return; 361167802Sjkim } 36267754Smsmith 363193267Sjkim /* If a particular signature is expected (DSDT/FACS), it must match */ 36467754Smsmith 365167802Sjkim if (Signature && 366193267Sjkim !ACPI_COMPARE_NAME (MappedTable->Signature, Signature)) 367167802Sjkim { 368193267Sjkim ACPI_ERROR ((AE_INFO, 369193267Sjkim "Invalid signature 0x%X for ACPI table, expected [%s]", 370193267Sjkim *ACPI_CAST_PTR (UINT32, MappedTable->Signature), Signature)); 371167802Sjkim goto UnmapAndExit; 372167802Sjkim } 37367754Smsmith 374193267Sjkim /* 375193267Sjkim * ACPI Table Override: 376193267Sjkim * 377193267Sjkim * Before we install the table, let the host OS override it with a new 378193267Sjkim * one if desired. Any table within the RSDT/XSDT can be replaced, 379193267Sjkim * including the DSDT which is pointed to by the FADT. 380193267Sjkim */ 381193267Sjkim Status = AcpiOsTableOverride (MappedTable, &OverrideTable); 382193267Sjkim if (ACPI_SUCCESS (Status) && OverrideTable) 383193267Sjkim { 384193267Sjkim ACPI_INFO ((AE_INFO, 385193267Sjkim "%4.4s @ 0x%p Table override, replaced with:", 386193267Sjkim MappedTable->Signature, ACPI_CAST_PTR (void, Address))); 387193267Sjkim 388193267Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Pointer = OverrideTable; 389193267Sjkim Address = ACPI_PTR_TO_PHYSADDR (OverrideTable); 390193267Sjkim 391193267Sjkim TableToInstall = OverrideTable; 392193267Sjkim Flags = ACPI_TABLE_ORIGIN_OVERRIDE; 393193267Sjkim } 394193267Sjkim else 395193267Sjkim { 396193267Sjkim TableToInstall = MappedTable; 397193267Sjkim Flags = ACPI_TABLE_ORIGIN_MAPPED; 398193267Sjkim } 399193267Sjkim 400167802Sjkim /* Initialize the table entry */ 401167802Sjkim 402167802Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Address = Address; 403193267Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Length = TableToInstall->Length; 404167802Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags = Flags; 405167802Sjkim 406167802Sjkim ACPI_MOVE_32_TO_32 ( 407167802Sjkim &(AcpiGbl_RootTableList.Tables[TableIndex].Signature), 408193267Sjkim TableToInstall->Signature); 409167802Sjkim 410193267Sjkim AcpiTbPrintTableHeader (Address, TableToInstall); 411167802Sjkim 412167802Sjkim if (TableIndex == ACPI_TABLE_INDEX_DSDT) 41367754Smsmith { 414167802Sjkim /* Global integer width is based upon revision of the DSDT */ 41567754Smsmith 416193267Sjkim AcpiUtSetIntegerWidth (TableToInstall->Revision); 41767754Smsmith } 418167802Sjkim 419167802SjkimUnmapAndExit: 420193267Sjkim AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER)); 42167754Smsmith} 42267754Smsmith 42367754Smsmith 42467754Smsmith/******************************************************************************* 42567754Smsmith * 426167802Sjkim * FUNCTION: AcpiTbGetRootTableEntry 42767754Smsmith * 428167802Sjkim * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry 429167802Sjkim * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT) 43067754Smsmith * 431167802Sjkim * RETURN: Physical address extracted from the root table 43267754Smsmith * 433167802Sjkim * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on 434167802Sjkim * both 32-bit and 64-bit platforms 43567754Smsmith * 436167802Sjkim * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on 437167802Sjkim * 64-bit platforms. 438167802Sjkim * 43967754Smsmith ******************************************************************************/ 44067754Smsmith 441167802Sjkimstatic ACPI_PHYSICAL_ADDRESS 442167802SjkimAcpiTbGetRootTableEntry ( 443167802Sjkim UINT8 *TableEntry, 444193267Sjkim UINT32 TableEntrySize) 44567754Smsmith{ 446167802Sjkim UINT64 Address64; 44767754Smsmith 44867754Smsmith 449167802Sjkim /* 450167802Sjkim * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): 451167802Sjkim * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT 452167802Sjkim */ 453167802Sjkim if (TableEntrySize == sizeof (UINT32)) 45467754Smsmith { 455167802Sjkim /* 456167802Sjkim * 32-bit platform, RSDT: Return 32-bit table entry 457167802Sjkim * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return 458167802Sjkim */ 459167802Sjkim return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry))); 460167802Sjkim } 461167802Sjkim else 462167802Sjkim { 463167802Sjkim /* 464167802Sjkim * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return 465193267Sjkim * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, 466193267Sjkim * return 64-bit 467167802Sjkim */ 468167802Sjkim ACPI_MOVE_64_TO_64 (&Address64, TableEntry); 46967754Smsmith 470167802Sjkim#if ACPI_MACHINE_WIDTH == 32 471167802Sjkim if (Address64 > ACPI_UINT32_MAX) 472167802Sjkim { 473167802Sjkim /* Will truncate 64-bit address to 32 bits, issue warning */ 47467754Smsmith 475167802Sjkim ACPI_WARNING ((AE_INFO, 476193267Sjkim "64-bit Physical Address in XSDT is too large (%8.8X%8.8X)," 477193267Sjkim " truncating", 478167802Sjkim ACPI_FORMAT_UINT64 (Address64))); 47967754Smsmith } 480167802Sjkim#endif 481167802Sjkim return ((ACPI_PHYSICAL_ADDRESS) (Address64)); 48267754Smsmith } 48367754Smsmith} 48467754Smsmith 48567754Smsmith 486151937Sjkim/******************************************************************************* 487151937Sjkim * 488167802Sjkim * FUNCTION: AcpiTbParseRootTable 489151937Sjkim * 490167802Sjkim * PARAMETERS: Rsdp - Pointer to the RSDP 491151937Sjkim * 492167802Sjkim * RETURN: Status 493151937Sjkim * 494167802Sjkim * DESCRIPTION: This function is called to parse the Root System Description 495167802Sjkim * Table (RSDT or XSDT) 496167802Sjkim * 497167802Sjkim * NOTE: Tables are mapped (not copied) for efficiency. The FACS must 498167802Sjkim * be mapped and cannot be copied because it contains the actual 499167802Sjkim * memory location of the ACPI Global Lock. 500167802Sjkim * 501151937Sjkim ******************************************************************************/ 502151937Sjkim 503151937SjkimACPI_STATUS 504167802SjkimAcpiTbParseRootTable ( 505193267Sjkim ACPI_PHYSICAL_ADDRESS RsdpAddress) 506151937Sjkim{ 507167802Sjkim ACPI_TABLE_RSDP *Rsdp; 508193267Sjkim UINT32 TableEntrySize; 509193267Sjkim UINT32 i; 510167802Sjkim UINT32 TableCount; 511167802Sjkim ACPI_TABLE_HEADER *Table; 512167802Sjkim ACPI_PHYSICAL_ADDRESS Address; 513167802Sjkim UINT32 Length; 514167802Sjkim UINT8 *TableEntry; 515167802Sjkim ACPI_STATUS Status; 516151937Sjkim 517151937Sjkim 518167802Sjkim ACPI_FUNCTION_TRACE (TbParseRootTable); 519151937Sjkim 520151937Sjkim 521167802Sjkim /* 522167802Sjkim * Map the entire RSDP and extract the address of the RSDT or XSDT 523167802Sjkim */ 524167802Sjkim Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP)); 525167802Sjkim if (!Rsdp) 526151937Sjkim { 527167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 528167802Sjkim } 529167802Sjkim 530193267Sjkim AcpiTbPrintTableHeader (RsdpAddress, 531193267Sjkim ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp)); 532167802Sjkim 533167802Sjkim /* Differentiate between RSDT and XSDT root tables */ 534167802Sjkim 535167802Sjkim if (Rsdp->Revision > 1 && Rsdp->XsdtPhysicalAddress) 536167802Sjkim { 537167802Sjkim /* 538167802Sjkim * Root table is an XSDT (64-bit physical addresses). We must use the 539167802Sjkim * XSDT if the revision is > 1 and the XSDT pointer is present, as per 540167802Sjkim * the ACPI specification. 541167802Sjkim */ 542167802Sjkim Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress; 543167802Sjkim TableEntrySize = sizeof (UINT64); 544167802Sjkim } 545167802Sjkim else 546167802Sjkim { 547167802Sjkim /* Root table is an RSDT (32-bit physical addresses) */ 548167802Sjkim 549167802Sjkim Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress; 550167802Sjkim TableEntrySize = sizeof (UINT32); 551167802Sjkim } 552167802Sjkim 553167802Sjkim /* 554167802Sjkim * It is not possible to map more than one entry in some environments, 555167802Sjkim * so unmap the RSDP here before mapping other tables 556167802Sjkim */ 557167802Sjkim AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP)); 558167802Sjkim 559167802Sjkim 560167802Sjkim /* Map the RSDT/XSDT table header to get the full table length */ 561167802Sjkim 562167802Sjkim Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 563167802Sjkim if (!Table) 564167802Sjkim { 565167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 566167802Sjkim } 567167802Sjkim 568167802Sjkim AcpiTbPrintTableHeader (Address, Table); 569167802Sjkim 570167802Sjkim /* Get the length of the full table, verify length and map entire table */ 571167802Sjkim 572167802Sjkim Length = Table->Length; 573167802Sjkim AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 574167802Sjkim 575167802Sjkim if (Length < sizeof (ACPI_TABLE_HEADER)) 576167802Sjkim { 577167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", Length)); 578167802Sjkim return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); 579167802Sjkim } 580167802Sjkim 581167802Sjkim Table = AcpiOsMapMemory (Address, Length); 582167802Sjkim if (!Table) 583167802Sjkim { 584167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 585167802Sjkim } 586167802Sjkim 587167802Sjkim /* Validate the root table checksum */ 588167802Sjkim 589167802Sjkim Status = AcpiTbVerifyChecksum (Table, Length); 590167802Sjkim if (ACPI_FAILURE (Status)) 591167802Sjkim { 592167802Sjkim AcpiOsUnmapMemory (Table, Length); 593167802Sjkim return_ACPI_STATUS (Status); 594167802Sjkim } 595167802Sjkim 596167802Sjkim /* Calculate the number of tables described in the root table */ 597167802Sjkim 598193267Sjkim TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) / 599193267Sjkim TableEntrySize); 600167802Sjkim 601167802Sjkim /* 602193267Sjkim * First two entries in the table array are reserved for the DSDT 603193267Sjkim * and FACS, which are not actually present in the RSDT/XSDT - they 604193267Sjkim * come from the FADT 605167802Sjkim */ 606167802Sjkim TableEntry = ACPI_CAST_PTR (UINT8, Table) + sizeof (ACPI_TABLE_HEADER); 607167802Sjkim AcpiGbl_RootTableList.Count = 2; 608167802Sjkim 609167802Sjkim /* 610167802Sjkim * Initialize the root table array from the RSDT/XSDT 611167802Sjkim */ 612167802Sjkim for (i = 0; i < TableCount; i++) 613167802Sjkim { 614167802Sjkim if (AcpiGbl_RootTableList.Count >= AcpiGbl_RootTableList.Size) 615151937Sjkim { 616167802Sjkim /* There is no more room in the root table array, attempt resize */ 617167802Sjkim 618167802Sjkim Status = AcpiTbResizeRootTableList (); 619167802Sjkim if (ACPI_FAILURE (Status)) 620151937Sjkim { 621167802Sjkim ACPI_WARNING ((AE_INFO, "Truncating %u table entries!", 622193267Sjkim (unsigned) (TableCount - 623193267Sjkim (AcpiGbl_RootTableList.Count - 2)))); 624167802Sjkim break; 625151937Sjkim } 626167802Sjkim } 627151937Sjkim 628167802Sjkim /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ 629167802Sjkim 630167802Sjkim AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Address = 631167802Sjkim AcpiTbGetRootTableEntry (TableEntry, TableEntrySize); 632167802Sjkim 633167802Sjkim TableEntry += TableEntrySize; 634167802Sjkim AcpiGbl_RootTableList.Count++; 635167802Sjkim } 636167802Sjkim 637167802Sjkim /* 638167802Sjkim * It is not possible to map more than one entry in some environments, 639167802Sjkim * so unmap the root table here before mapping other tables 640167802Sjkim */ 641167802Sjkim AcpiOsUnmapMemory (Table, Length); 642167802Sjkim 643167802Sjkim /* 644167802Sjkim * Complete the initialization of the root table array by examining 645167802Sjkim * the header of each table 646167802Sjkim */ 647167802Sjkim for (i = 2; i < AcpiGbl_RootTableList.Count; i++) 648167802Sjkim { 649167802Sjkim AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address, 650193267Sjkim NULL, i); 651167802Sjkim 652167802Sjkim /* Special case for FADT - get the DSDT and FACS */ 653167802Sjkim 654167802Sjkim if (ACPI_COMPARE_NAME ( 655167802Sjkim &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT)) 656167802Sjkim { 657193267Sjkim AcpiTbParseFadt (i); 658151937Sjkim } 659151937Sjkim } 660151937Sjkim 661167802Sjkim return_ACPI_STATUS (AE_OK); 662151937Sjkim} 663