1263851Sjkim/****************************************************************************** 2263851Sjkim * 3263851Sjkim * Module Name: tbdata - Table manager data structure functions 4263851Sjkim * 5263851Sjkim *****************************************************************************/ 6263851Sjkim 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12263851Sjkim * All rights reserved. 13263851Sjkim * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119263851Sjkim * Redistribution and use in source and binary forms, with or without 120263851Sjkim * modification, are permitted provided that the following conditions 121263851Sjkim * are met: 122263851Sjkim * 1. Redistributions of source code must retain the above copyright 123263851Sjkim * notice, this list of conditions, and the following disclaimer, 124263851Sjkim * without modification. 125263851Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126263851Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127263851Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128263851Sjkim * including a substantially similar Disclaimer requirement for further 129263851Sjkim * binary redistribution. 130263851Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131263851Sjkim * of any contributors may be used to endorse or promote products derived 132263851Sjkim * from this software without specific prior written permission. 133263851Sjkim * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147263851Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148263851Sjkim * Software Foundation. 149263851Sjkim * 150316303Sjkim *****************************************************************************/ 151263851Sjkim 152272444Sjkim#include <contrib/dev/acpica/include/acpi.h> 153272444Sjkim#include <contrib/dev/acpica/include/accommon.h> 154272444Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 155272444Sjkim#include <contrib/dev/acpica/include/actables.h> 156316303Sjkim#include <contrib/dev/acpica/include/acevents.h> 157263851Sjkim 158263851Sjkim#define _COMPONENT ACPI_TABLES 159263851Sjkim ACPI_MODULE_NAME ("tbdata") 160263851Sjkim 161322877Sjkim/* Local prototypes */ 162263851Sjkim 163322877Sjkimstatic ACPI_STATUS 164322877SjkimAcpiTbCheckDuplication ( 165322877Sjkim ACPI_TABLE_DESC *TableDesc, 166322877Sjkim UINT32 *TableIndex); 167322877Sjkim 168322877Sjkimstatic BOOLEAN 169322877SjkimAcpiTbCompareTables ( 170322877Sjkim ACPI_TABLE_DESC *TableDesc, 171322877Sjkim UINT32 TableIndex); 172322877Sjkim 173322877Sjkim 174263851Sjkim/******************************************************************************* 175263851Sjkim * 176322877Sjkim * FUNCTION: AcpiTbCompareTables 177322877Sjkim * 178322877Sjkim * PARAMETERS: TableDesc - Table 1 descriptor to be compared 179322877Sjkim * TableIndex - Index of table 2 to be compared 180322877Sjkim * 181322877Sjkim * RETURN: TRUE if both tables are identical. 182322877Sjkim * 183322877Sjkim * DESCRIPTION: This function compares a table with another table that has 184322877Sjkim * already been installed in the root table list. 185322877Sjkim * 186322877Sjkim ******************************************************************************/ 187322877Sjkim 188322877Sjkimstatic BOOLEAN 189322877SjkimAcpiTbCompareTables ( 190322877Sjkim ACPI_TABLE_DESC *TableDesc, 191322877Sjkim UINT32 TableIndex) 192322877Sjkim{ 193322877Sjkim ACPI_STATUS Status = AE_OK; 194322877Sjkim BOOLEAN IsIdentical; 195322877Sjkim ACPI_TABLE_HEADER *Table; 196322877Sjkim UINT32 TableLength; 197322877Sjkim UINT8 TableFlags; 198322877Sjkim 199322877Sjkim 200322877Sjkim Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex], 201322877Sjkim &Table, &TableLength, &TableFlags); 202322877Sjkim if (ACPI_FAILURE (Status)) 203322877Sjkim { 204322877Sjkim return (FALSE); 205322877Sjkim } 206322877Sjkim 207322877Sjkim /* 208322877Sjkim * Check for a table match on the entire table length, 209322877Sjkim * not just the header. 210322877Sjkim */ 211322877Sjkim IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength || 212322877Sjkim memcmp (TableDesc->Pointer, Table, TableLength)) ? 213322877Sjkim FALSE : TRUE); 214322877Sjkim 215322877Sjkim /* Release the acquired table */ 216322877Sjkim 217322877Sjkim AcpiTbReleaseTable (Table, TableLength, TableFlags); 218322877Sjkim return (IsIdentical); 219322877Sjkim} 220322877Sjkim 221322877Sjkim 222322877Sjkim/******************************************************************************* 223322877Sjkim * 224263851Sjkim * FUNCTION: AcpiTbInitTableDescriptor 225263851Sjkim * 226263851Sjkim * PARAMETERS: TableDesc - Table descriptor 227263851Sjkim * Address - Physical address of the table 228263851Sjkim * Flags - Allocation flags of the table 229263851Sjkim * Table - Pointer to the table 230263851Sjkim * 231263851Sjkim * RETURN: None 232263851Sjkim * 233263851Sjkim * DESCRIPTION: Initialize a new table descriptor 234263851Sjkim * 235263851Sjkim ******************************************************************************/ 236263851Sjkim 237263851Sjkimvoid 238263851SjkimAcpiTbInitTableDescriptor ( 239263851Sjkim ACPI_TABLE_DESC *TableDesc, 240263851Sjkim ACPI_PHYSICAL_ADDRESS Address, 241263851Sjkim UINT8 Flags, 242263851Sjkim ACPI_TABLE_HEADER *Table) 243263851Sjkim{ 244263851Sjkim 245263851Sjkim /* 246263851Sjkim * Initialize the table descriptor. Set the pointer to NULL, since the 247263851Sjkim * table is not fully mapped at this time. 248263851Sjkim */ 249284583Sjkim memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC)); 250263851Sjkim TableDesc->Address = Address; 251263851Sjkim TableDesc->Length = Table->Length; 252263851Sjkim TableDesc->Flags = Flags; 253263851Sjkim ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); 254263851Sjkim} 255263851Sjkim 256263851Sjkim 257263851Sjkim/******************************************************************************* 258263851Sjkim * 259263851Sjkim * FUNCTION: AcpiTbAcquireTable 260263851Sjkim * 261263851Sjkim * PARAMETERS: TableDesc - Table descriptor 262263851Sjkim * TablePtr - Where table is returned 263263851Sjkim * TableLength - Where table length is returned 264263851Sjkim * TableFlags - Where table allocation flags are returned 265263851Sjkim * 266263851Sjkim * RETURN: Status 267263851Sjkim * 268263851Sjkim * DESCRIPTION: Acquire an ACPI table. It can be used for tables not 269263851Sjkim * maintained in the AcpiGbl_RootTableList. 270263851Sjkim * 271263851Sjkim ******************************************************************************/ 272263851Sjkim 273263851SjkimACPI_STATUS 274263851SjkimAcpiTbAcquireTable ( 275263851Sjkim ACPI_TABLE_DESC *TableDesc, 276263851Sjkim ACPI_TABLE_HEADER **TablePtr, 277263851Sjkim UINT32 *TableLength, 278263851Sjkim UINT8 *TableFlags) 279263851Sjkim{ 280263851Sjkim ACPI_TABLE_HEADER *Table = NULL; 281263851Sjkim 282263851Sjkim 283263851Sjkim switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 284263851Sjkim { 285263851Sjkim case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 286263851Sjkim 287263851Sjkim Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length); 288263851Sjkim break; 289263851Sjkim 290263851Sjkim case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 291263851Sjkim case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 292263851Sjkim 293281396Sjkim Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 294298714Sjkim ACPI_PHYSADDR_TO_PTR (TableDesc->Address)); 295263851Sjkim break; 296263851Sjkim 297263851Sjkim default: 298263851Sjkim 299263851Sjkim break; 300263851Sjkim } 301263851Sjkim 302263851Sjkim /* Table is not valid yet */ 303263851Sjkim 304263851Sjkim if (!Table) 305263851Sjkim { 306263851Sjkim return (AE_NO_MEMORY); 307263851Sjkim } 308263851Sjkim 309263851Sjkim /* Fill the return values */ 310263851Sjkim 311263851Sjkim *TablePtr = Table; 312263851Sjkim *TableLength = TableDesc->Length; 313263851Sjkim *TableFlags = TableDesc->Flags; 314263851Sjkim return (AE_OK); 315263851Sjkim} 316263851Sjkim 317263851Sjkim 318263851Sjkim/******************************************************************************* 319263851Sjkim * 320263851Sjkim * FUNCTION: AcpiTbReleaseTable 321263851Sjkim * 322263851Sjkim * PARAMETERS: Table - Pointer for the table 323263851Sjkim * TableLength - Length for the table 324263851Sjkim * TableFlags - Allocation flags for the table 325263851Sjkim * 326263851Sjkim * RETURN: None 327263851Sjkim * 328263851Sjkim * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable(). 329263851Sjkim * 330263851Sjkim ******************************************************************************/ 331263851Sjkim 332263851Sjkimvoid 333263851SjkimAcpiTbReleaseTable ( 334263851Sjkim ACPI_TABLE_HEADER *Table, 335263851Sjkim UINT32 TableLength, 336263851Sjkim UINT8 TableFlags) 337263851Sjkim{ 338263851Sjkim 339263851Sjkim switch (TableFlags & ACPI_TABLE_ORIGIN_MASK) 340263851Sjkim { 341263851Sjkim case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 342263851Sjkim 343263851Sjkim AcpiOsUnmapMemory (Table, TableLength); 344263851Sjkim break; 345263851Sjkim 346263851Sjkim case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 347263851Sjkim case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 348263851Sjkim default: 349263851Sjkim 350263851Sjkim break; 351263851Sjkim } 352263851Sjkim} 353263851Sjkim 354263851Sjkim 355263851Sjkim/******************************************************************************* 356263851Sjkim * 357263851Sjkim * FUNCTION: AcpiTbAcquireTempTable 358263851Sjkim * 359263851Sjkim * PARAMETERS: TableDesc - Table descriptor to be acquired 360263851Sjkim * Address - Address of the table 361263851Sjkim * Flags - Allocation flags of the table 362263851Sjkim * 363263851Sjkim * RETURN: Status 364263851Sjkim * 365263851Sjkim * DESCRIPTION: This function validates the table header to obtain the length 366263851Sjkim * of a table and fills the table descriptor to make its state as 367263851Sjkim * "INSTALLED". Such a table descriptor is only used for verified 368263851Sjkim * installation. 369263851Sjkim * 370263851Sjkim ******************************************************************************/ 371263851Sjkim 372263851SjkimACPI_STATUS 373263851SjkimAcpiTbAcquireTempTable ( 374263851Sjkim ACPI_TABLE_DESC *TableDesc, 375263851Sjkim ACPI_PHYSICAL_ADDRESS Address, 376263851Sjkim UINT8 Flags) 377263851Sjkim{ 378263851Sjkim ACPI_TABLE_HEADER *TableHeader; 379263851Sjkim 380263851Sjkim 381263851Sjkim switch (Flags & ACPI_TABLE_ORIGIN_MASK) 382263851Sjkim { 383263851Sjkim case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 384263851Sjkim 385263851Sjkim /* Get the length of the full table from the header */ 386263851Sjkim 387263851Sjkim TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 388263851Sjkim if (!TableHeader) 389263851Sjkim { 390263851Sjkim return (AE_NO_MEMORY); 391263851Sjkim } 392263851Sjkim 393263851Sjkim AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); 394263851Sjkim AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER)); 395263851Sjkim return (AE_OK); 396263851Sjkim 397263851Sjkim case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 398263851Sjkim case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 399263851Sjkim 400281396Sjkim TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 401298714Sjkim ACPI_PHYSADDR_TO_PTR (Address)); 402263851Sjkim if (!TableHeader) 403263851Sjkim { 404263851Sjkim return (AE_NO_MEMORY); 405263851Sjkim } 406263851Sjkim 407263851Sjkim AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); 408263851Sjkim return (AE_OK); 409263851Sjkim 410263851Sjkim default: 411263851Sjkim 412263851Sjkim break; 413263851Sjkim } 414263851Sjkim 415263851Sjkim /* Table is not valid yet */ 416263851Sjkim 417263851Sjkim return (AE_NO_MEMORY); 418263851Sjkim} 419263851Sjkim 420263851Sjkim 421263851Sjkim/******************************************************************************* 422263851Sjkim * 423263851Sjkim * FUNCTION: AcpiTbReleaseTempTable 424263851Sjkim * 425263851Sjkim * PARAMETERS: TableDesc - Table descriptor to be released 426263851Sjkim * 427263851Sjkim * RETURN: Status 428263851Sjkim * 429263851Sjkim * DESCRIPTION: The inverse of AcpiTbAcquireTempTable(). 430263851Sjkim * 431263851Sjkim *****************************************************************************/ 432263851Sjkim 433263851Sjkimvoid 434263851SjkimAcpiTbReleaseTempTable ( 435263851Sjkim ACPI_TABLE_DESC *TableDesc) 436263851Sjkim{ 437263851Sjkim 438263851Sjkim /* 439263851Sjkim * Note that the .Address is maintained by the callers of 440263851Sjkim * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable() 441263851Sjkim * where .Address will be freed. 442263851Sjkim */ 443263851Sjkim AcpiTbInvalidateTable (TableDesc); 444263851Sjkim} 445263851Sjkim 446263851Sjkim 447263851Sjkim/****************************************************************************** 448263851Sjkim * 449263851Sjkim * FUNCTION: AcpiTbValidateTable 450263851Sjkim * 451263851Sjkim * PARAMETERS: TableDesc - Table descriptor 452263851Sjkim * 453263851Sjkim * RETURN: Status 454263851Sjkim * 455263851Sjkim * DESCRIPTION: This function is called to validate the table, the returned 456263851Sjkim * table descriptor is in "VALIDATED" state. 457263851Sjkim * 458263851Sjkim *****************************************************************************/ 459263851Sjkim 460263851SjkimACPI_STATUS 461263851SjkimAcpiTbValidateTable ( 462263851Sjkim ACPI_TABLE_DESC *TableDesc) 463263851Sjkim{ 464263851Sjkim ACPI_STATUS Status = AE_OK; 465263851Sjkim 466263851Sjkim 467263851Sjkim ACPI_FUNCTION_TRACE (TbValidateTable); 468263851Sjkim 469263851Sjkim 470263851Sjkim /* Validate the table if necessary */ 471263851Sjkim 472263851Sjkim if (!TableDesc->Pointer) 473263851Sjkim { 474263851Sjkim Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer, 475298714Sjkim &TableDesc->Length, &TableDesc->Flags); 476263851Sjkim if (!TableDesc->Pointer) 477263851Sjkim { 478263851Sjkim Status = AE_NO_MEMORY; 479263851Sjkim } 480263851Sjkim } 481263851Sjkim 482263851Sjkim return_ACPI_STATUS (Status); 483263851Sjkim} 484263851Sjkim 485263851Sjkim 486263851Sjkim/******************************************************************************* 487263851Sjkim * 488263851Sjkim * FUNCTION: AcpiTbInvalidateTable 489263851Sjkim * 490263851Sjkim * PARAMETERS: TableDesc - Table descriptor 491263851Sjkim * 492263851Sjkim * RETURN: None 493263851Sjkim * 494263851Sjkim * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of 495263851Sjkim * AcpiTbValidateTable(). 496263851Sjkim * 497263851Sjkim ******************************************************************************/ 498263851Sjkim 499263851Sjkimvoid 500263851SjkimAcpiTbInvalidateTable ( 501263851Sjkim ACPI_TABLE_DESC *TableDesc) 502263851Sjkim{ 503263851Sjkim 504263851Sjkim ACPI_FUNCTION_TRACE (TbInvalidateTable); 505263851Sjkim 506263851Sjkim 507263851Sjkim /* Table must be validated */ 508263851Sjkim 509263851Sjkim if (!TableDesc->Pointer) 510263851Sjkim { 511263851Sjkim return_VOID; 512263851Sjkim } 513263851Sjkim 514263851Sjkim AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length, 515263851Sjkim TableDesc->Flags); 516263851Sjkim TableDesc->Pointer = NULL; 517263851Sjkim 518263851Sjkim return_VOID; 519263851Sjkim} 520263851Sjkim 521263851Sjkim 522263851Sjkim/****************************************************************************** 523263851Sjkim * 524272444Sjkim * FUNCTION: AcpiTbValidateTempTable 525263851Sjkim * 526263851Sjkim * PARAMETERS: TableDesc - Table descriptor 527272444Sjkim * 528272444Sjkim * RETURN: Status 529272444Sjkim * 530272444Sjkim * DESCRIPTION: This function is called to validate the table, the returned 531272444Sjkim * table descriptor is in "VALIDATED" state. 532272444Sjkim * 533272444Sjkim *****************************************************************************/ 534272444Sjkim 535272444SjkimACPI_STATUS 536272444SjkimAcpiTbValidateTempTable ( 537272444Sjkim ACPI_TABLE_DESC *TableDesc) 538272444Sjkim{ 539272444Sjkim 540322877Sjkim if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation) 541272444Sjkim { 542272444Sjkim /* 543272444Sjkim * Only validates the header of the table. 544272444Sjkim * Note that Length contains the size of the mapping after invoking 545272444Sjkim * this work around, this value is required by 546272444Sjkim * AcpiTbReleaseTempTable(). 547272444Sjkim * We can do this because in AcpiInitTableDescriptor(), the Length 548272444Sjkim * field of the installed descriptor is filled with the actual 549272444Sjkim * table length obtaining from the table header. 550272444Sjkim */ 551272444Sjkim TableDesc->Length = sizeof (ACPI_TABLE_HEADER); 552272444Sjkim } 553272444Sjkim 554272444Sjkim return (AcpiTbValidateTable (TableDesc)); 555272444Sjkim} 556272444Sjkim 557272444Sjkim 558322877Sjkim/******************************************************************************* 559322877Sjkim * 560322877Sjkim * FUNCTION: AcpiTbCheckDuplication 561322877Sjkim * 562322877Sjkim * PARAMETERS: TableDesc - Table descriptor 563322877Sjkim * TableIndex - Where the table index is returned 564322877Sjkim * 565322877Sjkim * RETURN: Status 566322877Sjkim * 567322877Sjkim * DESCRIPTION: Avoid installing duplicated tables. However table override and 568322877Sjkim * user aided dynamic table load is allowed, thus comparing the 569322877Sjkim * address of the table is not sufficient, and checking the entire 570322877Sjkim * table content is required. 571322877Sjkim * 572322877Sjkim ******************************************************************************/ 573322877Sjkim 574322877Sjkimstatic ACPI_STATUS 575322877SjkimAcpiTbCheckDuplication ( 576322877Sjkim ACPI_TABLE_DESC *TableDesc, 577322877Sjkim UINT32 *TableIndex) 578322877Sjkim{ 579322877Sjkim UINT32 i; 580322877Sjkim 581322877Sjkim 582322877Sjkim ACPI_FUNCTION_TRACE (TbCheckDuplication); 583322877Sjkim 584322877Sjkim 585322877Sjkim /* Check if table is already registered */ 586322877Sjkim 587322877Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 588322877Sjkim { 589322877Sjkim /* Do not compare with unverified tables */ 590322877Sjkim 591322877Sjkim if (!(AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_VERIFIED)) 592322877Sjkim { 593322877Sjkim continue; 594322877Sjkim } 595322877Sjkim 596322877Sjkim /* 597322877Sjkim * Check for a table match on the entire table length, 598322877Sjkim * not just the header. 599322877Sjkim */ 600322877Sjkim if (!AcpiTbCompareTables (TableDesc, i)) 601322877Sjkim { 602322877Sjkim continue; 603322877Sjkim } 604322877Sjkim 605322877Sjkim /* 606322877Sjkim * Note: the current mechanism does not unregister a table if it is 607322877Sjkim * dynamically unloaded. The related namespace entries are deleted, 608322877Sjkim * but the table remains in the root table list. 609322877Sjkim * 610322877Sjkim * The assumption here is that the number of different tables that 611322877Sjkim * will be loaded is actually small, and there is minimal overhead 612322877Sjkim * in just keeping the table in case it is needed again. 613322877Sjkim * 614322877Sjkim * If this assumption changes in the future (perhaps on large 615322877Sjkim * machines with many table load/unload operations), tables will 616322877Sjkim * need to be unregistered when they are unloaded, and slots in the 617322877Sjkim * root table list should be reused when empty. 618322877Sjkim */ 619322877Sjkim if (AcpiGbl_RootTableList.Tables[i].Flags & 620322877Sjkim ACPI_TABLE_IS_LOADED) 621322877Sjkim { 622322877Sjkim /* Table is still loaded, this is an error */ 623322877Sjkim 624322877Sjkim return_ACPI_STATUS (AE_ALREADY_EXISTS); 625322877Sjkim } 626322877Sjkim else 627322877Sjkim { 628322877Sjkim *TableIndex = i; 629322877Sjkim return_ACPI_STATUS (AE_CTRL_TERMINATE); 630322877Sjkim } 631322877Sjkim } 632322877Sjkim 633322877Sjkim /* Indicate no duplication to the caller */ 634322877Sjkim 635322877Sjkim return_ACPI_STATUS (AE_OK); 636322877Sjkim} 637322877Sjkim 638322877Sjkim 639272444Sjkim/****************************************************************************** 640272444Sjkim * 641272444Sjkim * FUNCTION: AcpiTbVerifyTempTable 642272444Sjkim * 643272444Sjkim * PARAMETERS: TableDesc - Table descriptor 644263851Sjkim * Signature - Table signature to verify 645322877Sjkim * TableIndex - Where the table index is returned 646263851Sjkim * 647263851Sjkim * RETURN: Status 648263851Sjkim * 649263851Sjkim * DESCRIPTION: This function is called to validate and verify the table, the 650263851Sjkim * returned table descriptor is in "VALIDATED" state. 651322877Sjkim * Note that 'TableIndex' is required to be set to !NULL to 652322877Sjkim * enable duplication check. 653263851Sjkim * 654263851Sjkim *****************************************************************************/ 655263851Sjkim 656263851SjkimACPI_STATUS 657272444SjkimAcpiTbVerifyTempTable ( 658263851Sjkim ACPI_TABLE_DESC *TableDesc, 659322877Sjkim char *Signature, 660322877Sjkim UINT32 *TableIndex) 661263851Sjkim{ 662263851Sjkim ACPI_STATUS Status = AE_OK; 663263851Sjkim 664263851Sjkim 665272444Sjkim ACPI_FUNCTION_TRACE (TbVerifyTempTable); 666263851Sjkim 667263851Sjkim 668263851Sjkim /* Validate the table */ 669263851Sjkim 670272444Sjkim Status = AcpiTbValidateTempTable (TableDesc); 671263851Sjkim if (ACPI_FAILURE (Status)) 672263851Sjkim { 673263851Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 674263851Sjkim } 675263851Sjkim 676263851Sjkim /* If a particular signature is expected (DSDT/FACS), it must match */ 677263851Sjkim 678263851Sjkim if (Signature && 679263851Sjkim !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature)) 680263851Sjkim { 681263851Sjkim ACPI_BIOS_ERROR ((AE_INFO, 682263851Sjkim "Invalid signature 0x%X for ACPI table, expected [%s]", 683263851Sjkim TableDesc->Signature.Integer, Signature)); 684263851Sjkim Status = AE_BAD_SIGNATURE; 685263851Sjkim goto InvalidateAndExit; 686263851Sjkim } 687263851Sjkim 688322877Sjkim if (AcpiGbl_EnableTableValidation) 689322877Sjkim { 690322877Sjkim /* Verify the checksum */ 691263851Sjkim 692272444Sjkim Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 693272444Sjkim if (ACPI_FAILURE (Status)) 694272444Sjkim { 695272444Sjkim ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 696281396Sjkim "%4.4s 0x%8.8X%8.8X" 697272444Sjkim " Attempted table install failed", 698298714Sjkim AcpiUtValidNameseg (TableDesc->Signature.Ascii) ? 699272444Sjkim TableDesc->Signature.Ascii : "????", 700281396Sjkim ACPI_FORMAT_UINT64 (TableDesc->Address))); 701298714Sjkim 702272444Sjkim goto InvalidateAndExit; 703272444Sjkim } 704322877Sjkim 705322877Sjkim /* Avoid duplications */ 706322877Sjkim 707322877Sjkim if (TableIndex) 708322877Sjkim { 709322877Sjkim Status = AcpiTbCheckDuplication (TableDesc, TableIndex); 710322877Sjkim if (ACPI_FAILURE (Status)) 711322877Sjkim { 712322877Sjkim if (Status != AE_CTRL_TERMINATE) 713322877Sjkim { 714322877Sjkim ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 715322877Sjkim "%4.4s 0x%8.8X%8.8X" 716322877Sjkim " Table is duplicated", 717322877Sjkim AcpiUtValidNameseg (TableDesc->Signature.Ascii) ? 718322877Sjkim TableDesc->Signature.Ascii : "????", 719322877Sjkim ACPI_FORMAT_UINT64 (TableDesc->Address))); 720322877Sjkim } 721322877Sjkim 722322877Sjkim goto InvalidateAndExit; 723322877Sjkim } 724322877Sjkim } 725322877Sjkim 726322877Sjkim TableDesc->Flags |= ACPI_TABLE_IS_VERIFIED; 727263851Sjkim } 728263851Sjkim 729322877Sjkim return_ACPI_STATUS (Status); 730263851Sjkim 731263851SjkimInvalidateAndExit: 732263851Sjkim AcpiTbInvalidateTable (TableDesc); 733263851Sjkim return_ACPI_STATUS (Status); 734263851Sjkim} 735263851Sjkim 736263851Sjkim 737263851Sjkim/******************************************************************************* 738263851Sjkim * 739263851Sjkim * FUNCTION: AcpiTbResizeRootTableList 740263851Sjkim * 741263851Sjkim * PARAMETERS: None 742263851Sjkim * 743263851Sjkim * RETURN: Status 744263851Sjkim * 745263851Sjkim * DESCRIPTION: Expand the size of global table array 746263851Sjkim * 747263851Sjkim ******************************************************************************/ 748263851Sjkim 749263851SjkimACPI_STATUS 750263851SjkimAcpiTbResizeRootTableList ( 751263851Sjkim void) 752263851Sjkim{ 753263851Sjkim ACPI_TABLE_DESC *Tables; 754263851Sjkim UINT32 TableCount; 755322877Sjkim UINT32 CurrentTableCount, MaxTableCount; 756322877Sjkim UINT32 i; 757263851Sjkim 758263851Sjkim 759263851Sjkim ACPI_FUNCTION_TRACE (TbResizeRootTableList); 760263851Sjkim 761263851Sjkim 762263851Sjkim /* AllowResize flag is a parameter to AcpiInitializeTables */ 763263851Sjkim 764263851Sjkim if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 765263851Sjkim { 766263851Sjkim ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 767263851Sjkim return_ACPI_STATUS (AE_SUPPORT); 768263851Sjkim } 769263851Sjkim 770263851Sjkim /* Increase the Table Array size */ 771263851Sjkim 772263851Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 773263851Sjkim { 774263851Sjkim TableCount = AcpiGbl_RootTableList.MaxTableCount; 775263851Sjkim } 776263851Sjkim else 777263851Sjkim { 778263851Sjkim TableCount = AcpiGbl_RootTableList.CurrentTableCount; 779263851Sjkim } 780263851Sjkim 781322877Sjkim MaxTableCount = TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; 782263851Sjkim Tables = ACPI_ALLOCATE_ZEROED ( 783322877Sjkim ((ACPI_SIZE) MaxTableCount) * sizeof (ACPI_TABLE_DESC)); 784263851Sjkim if (!Tables) 785263851Sjkim { 786263851Sjkim ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 787263851Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 788263851Sjkim } 789263851Sjkim 790263851Sjkim /* Copy and free the previous table array */ 791263851Sjkim 792322877Sjkim CurrentTableCount = 0; 793263851Sjkim if (AcpiGbl_RootTableList.Tables) 794263851Sjkim { 795322877Sjkim for (i = 0; i < TableCount; i++) 796322877Sjkim { 797322877Sjkim if (AcpiGbl_RootTableList.Tables[i].Address) 798322877Sjkim { 799322877Sjkim memcpy (Tables + CurrentTableCount, 800322877Sjkim AcpiGbl_RootTableList.Tables + i, 801322877Sjkim sizeof (ACPI_TABLE_DESC)); 802322877Sjkim CurrentTableCount++; 803322877Sjkim } 804322877Sjkim } 805263851Sjkim 806263851Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 807263851Sjkim { 808263851Sjkim ACPI_FREE (AcpiGbl_RootTableList.Tables); 809263851Sjkim } 810263851Sjkim } 811263851Sjkim 812263851Sjkim AcpiGbl_RootTableList.Tables = Tables; 813322877Sjkim AcpiGbl_RootTableList.MaxTableCount = MaxTableCount; 814322877Sjkim AcpiGbl_RootTableList.CurrentTableCount = CurrentTableCount; 815263851Sjkim AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 816263851Sjkim 817263851Sjkim return_ACPI_STATUS (AE_OK); 818263851Sjkim} 819263851Sjkim 820263851Sjkim 821263851Sjkim/******************************************************************************* 822263851Sjkim * 823281396Sjkim * FUNCTION: AcpiTbGetNextTableDescriptor 824263851Sjkim * 825263851Sjkim * PARAMETERS: TableIndex - Where table index is returned 826281396Sjkim * TableDesc - Where table descriptor is returned 827263851Sjkim * 828281396Sjkim * RETURN: Status and table index/descriptor. 829263851Sjkim * 830263851Sjkim * DESCRIPTION: Allocate a new ACPI table entry to the global table list 831263851Sjkim * 832263851Sjkim ******************************************************************************/ 833263851Sjkim 834263851SjkimACPI_STATUS 835281396SjkimAcpiTbGetNextTableDescriptor ( 836281396Sjkim UINT32 *TableIndex, 837281396Sjkim ACPI_TABLE_DESC **TableDesc) 838263851Sjkim{ 839263851Sjkim ACPI_STATUS Status; 840281396Sjkim UINT32 i; 841263851Sjkim 842263851Sjkim 843263851Sjkim /* Ensure that there is room for the table in the Root Table List */ 844263851Sjkim 845263851Sjkim if (AcpiGbl_RootTableList.CurrentTableCount >= 846263851Sjkim AcpiGbl_RootTableList.MaxTableCount) 847263851Sjkim { 848263851Sjkim Status = AcpiTbResizeRootTableList(); 849263851Sjkim if (ACPI_FAILURE (Status)) 850263851Sjkim { 851263851Sjkim return (Status); 852263851Sjkim } 853263851Sjkim } 854263851Sjkim 855281396Sjkim i = AcpiGbl_RootTableList.CurrentTableCount; 856263851Sjkim AcpiGbl_RootTableList.CurrentTableCount++; 857281396Sjkim 858281396Sjkim if (TableIndex) 859281396Sjkim { 860281396Sjkim *TableIndex = i; 861281396Sjkim } 862281396Sjkim if (TableDesc) 863281396Sjkim { 864281396Sjkim *TableDesc = &AcpiGbl_RootTableList.Tables[i]; 865281396Sjkim } 866281396Sjkim 867263851Sjkim return (AE_OK); 868263851Sjkim} 869263851Sjkim 870263851Sjkim 871263851Sjkim/******************************************************************************* 872263851Sjkim * 873263851Sjkim * FUNCTION: AcpiTbTerminate 874263851Sjkim * 875263851Sjkim * PARAMETERS: None 876263851Sjkim * 877263851Sjkim * RETURN: None 878263851Sjkim * 879263851Sjkim * DESCRIPTION: Delete all internal ACPI tables 880263851Sjkim * 881263851Sjkim ******************************************************************************/ 882263851Sjkim 883263851Sjkimvoid 884263851SjkimAcpiTbTerminate ( 885263851Sjkim void) 886263851Sjkim{ 887263851Sjkim UINT32 i; 888263851Sjkim 889263851Sjkim 890263851Sjkim ACPI_FUNCTION_TRACE (TbTerminate); 891263851Sjkim 892263851Sjkim 893263851Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 894263851Sjkim 895263851Sjkim /* Delete the individual tables */ 896263851Sjkim 897263851Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 898263851Sjkim { 899263851Sjkim AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]); 900263851Sjkim } 901263851Sjkim 902263851Sjkim /* 903263851Sjkim * Delete the root table array if allocated locally. Array cannot be 904263851Sjkim * mapped, so we don't need to check for that flag. 905263851Sjkim */ 906263851Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 907263851Sjkim { 908263851Sjkim ACPI_FREE (AcpiGbl_RootTableList.Tables); 909263851Sjkim } 910263851Sjkim 911263851Sjkim AcpiGbl_RootTableList.Tables = NULL; 912263851Sjkim AcpiGbl_RootTableList.Flags = 0; 913263851Sjkim AcpiGbl_RootTableList.CurrentTableCount = 0; 914263851Sjkim 915263851Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 916263851Sjkim 917263851Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 918263851Sjkim return_VOID; 919263851Sjkim} 920263851Sjkim 921263851Sjkim 922263851Sjkim/******************************************************************************* 923263851Sjkim * 924263851Sjkim * FUNCTION: AcpiTbDeleteNamespaceByOwner 925263851Sjkim * 926263851Sjkim * PARAMETERS: TableIndex - Table index 927263851Sjkim * 928263851Sjkim * RETURN: Status 929263851Sjkim * 930263851Sjkim * DESCRIPTION: Delete all namespace objects created when this table was loaded. 931263851Sjkim * 932263851Sjkim ******************************************************************************/ 933263851Sjkim 934263851SjkimACPI_STATUS 935263851SjkimAcpiTbDeleteNamespaceByOwner ( 936263851Sjkim UINT32 TableIndex) 937263851Sjkim{ 938263851Sjkim ACPI_OWNER_ID OwnerId; 939263851Sjkim ACPI_STATUS Status; 940263851Sjkim 941263851Sjkim 942263851Sjkim ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 943263851Sjkim 944263851Sjkim 945263851Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 946263851Sjkim if (ACPI_FAILURE (Status)) 947263851Sjkim { 948263851Sjkim return_ACPI_STATUS (Status); 949263851Sjkim } 950263851Sjkim 951263851Sjkim if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 952263851Sjkim { 953263851Sjkim /* The table index does not exist */ 954263851Sjkim 955263851Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 956263851Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 957263851Sjkim } 958263851Sjkim 959263851Sjkim /* Get the owner ID for this table, used to delete namespace nodes */ 960263851Sjkim 961263851Sjkim OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 962263851Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 963263851Sjkim 964263851Sjkim /* 965263851Sjkim * Need to acquire the namespace writer lock to prevent interference 966263851Sjkim * with any concurrent namespace walks. The interpreter must be 967263851Sjkim * released during the deletion since the acquisition of the deletion 968263851Sjkim * lock may block, and also since the execution of a namespace walk 969263851Sjkim * must be allowed to use the interpreter. 970263851Sjkim */ 971263851Sjkim Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 972263851Sjkim if (ACPI_FAILURE (Status)) 973263851Sjkim { 974263851Sjkim return_ACPI_STATUS (Status); 975263851Sjkim } 976316303Sjkim AcpiNsDeleteNamespaceByOwner (OwnerId); 977263851Sjkim AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 978263851Sjkim return_ACPI_STATUS (Status); 979263851Sjkim} 980263851Sjkim 981263851Sjkim 982263851Sjkim/******************************************************************************* 983263851Sjkim * 984263851Sjkim * FUNCTION: AcpiTbAllocateOwnerId 985263851Sjkim * 986263851Sjkim * PARAMETERS: TableIndex - Table index 987263851Sjkim * 988263851Sjkim * RETURN: Status 989263851Sjkim * 990263851Sjkim * DESCRIPTION: Allocates OwnerId in TableDesc 991263851Sjkim * 992263851Sjkim ******************************************************************************/ 993263851Sjkim 994263851SjkimACPI_STATUS 995263851SjkimAcpiTbAllocateOwnerId ( 996263851Sjkim UINT32 TableIndex) 997263851Sjkim{ 998263851Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 999263851Sjkim 1000263851Sjkim 1001263851Sjkim ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 1002263851Sjkim 1003263851Sjkim 1004263851Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1005263851Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1006263851Sjkim { 1007263851Sjkim Status = AcpiUtAllocateOwnerId ( 1008298714Sjkim &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 1009263851Sjkim } 1010263851Sjkim 1011263851Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1012263851Sjkim return_ACPI_STATUS (Status); 1013263851Sjkim} 1014263851Sjkim 1015263851Sjkim 1016263851Sjkim/******************************************************************************* 1017263851Sjkim * 1018263851Sjkim * FUNCTION: AcpiTbReleaseOwnerId 1019263851Sjkim * 1020263851Sjkim * PARAMETERS: TableIndex - Table index 1021263851Sjkim * 1022263851Sjkim * RETURN: Status 1023263851Sjkim * 1024263851Sjkim * DESCRIPTION: Releases OwnerId in TableDesc 1025263851Sjkim * 1026263851Sjkim ******************************************************************************/ 1027263851Sjkim 1028263851SjkimACPI_STATUS 1029263851SjkimAcpiTbReleaseOwnerId ( 1030263851Sjkim UINT32 TableIndex) 1031263851Sjkim{ 1032263851Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 1033263851Sjkim 1034263851Sjkim 1035263851Sjkim ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 1036263851Sjkim 1037263851Sjkim 1038263851Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1039263851Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1040263851Sjkim { 1041263851Sjkim AcpiUtReleaseOwnerId ( 1042263851Sjkim &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 1043263851Sjkim Status = AE_OK; 1044263851Sjkim } 1045263851Sjkim 1046263851Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1047263851Sjkim return_ACPI_STATUS (Status); 1048263851Sjkim} 1049263851Sjkim 1050263851Sjkim 1051263851Sjkim/******************************************************************************* 1052263851Sjkim * 1053263851Sjkim * FUNCTION: AcpiTbGetOwnerId 1054263851Sjkim * 1055263851Sjkim * PARAMETERS: TableIndex - Table index 1056263851Sjkim * OwnerId - Where the table OwnerId is returned 1057263851Sjkim * 1058263851Sjkim * RETURN: Status 1059263851Sjkim * 1060263851Sjkim * DESCRIPTION: returns OwnerId for the ACPI table 1061263851Sjkim * 1062263851Sjkim ******************************************************************************/ 1063263851Sjkim 1064263851SjkimACPI_STATUS 1065263851SjkimAcpiTbGetOwnerId ( 1066263851Sjkim UINT32 TableIndex, 1067263851Sjkim ACPI_OWNER_ID *OwnerId) 1068263851Sjkim{ 1069263851Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 1070263851Sjkim 1071263851Sjkim 1072263851Sjkim ACPI_FUNCTION_TRACE (TbGetOwnerId); 1073263851Sjkim 1074263851Sjkim 1075263851Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1076263851Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1077263851Sjkim { 1078263851Sjkim *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 1079263851Sjkim Status = AE_OK; 1080263851Sjkim } 1081263851Sjkim 1082263851Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1083263851Sjkim return_ACPI_STATUS (Status); 1084263851Sjkim} 1085263851Sjkim 1086263851Sjkim 1087263851Sjkim/******************************************************************************* 1088263851Sjkim * 1089263851Sjkim * FUNCTION: AcpiTbIsTableLoaded 1090263851Sjkim * 1091263851Sjkim * PARAMETERS: TableIndex - Index into the root table 1092263851Sjkim * 1093263851Sjkim * RETURN: Table Loaded Flag 1094263851Sjkim * 1095263851Sjkim ******************************************************************************/ 1096263851Sjkim 1097263851SjkimBOOLEAN 1098263851SjkimAcpiTbIsTableLoaded ( 1099263851Sjkim UINT32 TableIndex) 1100263851Sjkim{ 1101263851Sjkim BOOLEAN IsLoaded = FALSE; 1102263851Sjkim 1103263851Sjkim 1104263851Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1105263851Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1106263851Sjkim { 1107263851Sjkim IsLoaded = (BOOLEAN) 1108263851Sjkim (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 1109263851Sjkim ACPI_TABLE_IS_LOADED); 1110263851Sjkim } 1111263851Sjkim 1112263851Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1113263851Sjkim return (IsLoaded); 1114263851Sjkim} 1115263851Sjkim 1116263851Sjkim 1117263851Sjkim/******************************************************************************* 1118263851Sjkim * 1119263851Sjkim * FUNCTION: AcpiTbSetTableLoadedFlag 1120263851Sjkim * 1121263851Sjkim * PARAMETERS: TableIndex - Table index 1122263851Sjkim * IsLoaded - TRUE if table is loaded, FALSE otherwise 1123263851Sjkim * 1124263851Sjkim * RETURN: None 1125263851Sjkim * 1126263851Sjkim * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 1127263851Sjkim * 1128263851Sjkim ******************************************************************************/ 1129263851Sjkim 1130263851Sjkimvoid 1131263851SjkimAcpiTbSetTableLoadedFlag ( 1132263851Sjkim UINT32 TableIndex, 1133263851Sjkim BOOLEAN IsLoaded) 1134263851Sjkim{ 1135263851Sjkim 1136263851Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1137263851Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1138263851Sjkim { 1139263851Sjkim if (IsLoaded) 1140263851Sjkim { 1141263851Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 1142263851Sjkim ACPI_TABLE_IS_LOADED; 1143263851Sjkim } 1144263851Sjkim else 1145263851Sjkim { 1146263851Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 1147263851Sjkim ~ACPI_TABLE_IS_LOADED; 1148263851Sjkim } 1149263851Sjkim } 1150263851Sjkim 1151263851Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1152263851Sjkim} 1153316303Sjkim 1154316303Sjkim 1155316303Sjkim/******************************************************************************* 1156316303Sjkim * 1157316303Sjkim * FUNCTION: AcpiTbLoadTable 1158316303Sjkim * 1159316303Sjkim * PARAMETERS: TableIndex - Table index 1160316303Sjkim * ParentNode - Where table index is returned 1161316303Sjkim * 1162316303Sjkim * RETURN: Status 1163316303Sjkim * 1164316303Sjkim * DESCRIPTION: Load an ACPI table 1165316303Sjkim * 1166316303Sjkim ******************************************************************************/ 1167316303Sjkim 1168316303SjkimACPI_STATUS 1169316303SjkimAcpiTbLoadTable ( 1170316303Sjkim UINT32 TableIndex, 1171316303Sjkim ACPI_NAMESPACE_NODE *ParentNode) 1172316303Sjkim{ 1173316303Sjkim ACPI_TABLE_HEADER *Table; 1174316303Sjkim ACPI_STATUS Status; 1175316303Sjkim ACPI_OWNER_ID OwnerId; 1176316303Sjkim 1177316303Sjkim 1178316303Sjkim ACPI_FUNCTION_TRACE (TbLoadTable); 1179316303Sjkim 1180316303Sjkim 1181316303Sjkim /* 1182316303Sjkim * Note: Now table is "INSTALLED", it must be validated before 1183316303Sjkim * using. 1184316303Sjkim */ 1185316303Sjkim Status = AcpiGetTableByIndex (TableIndex, &Table); 1186316303Sjkim if (ACPI_FAILURE (Status)) 1187316303Sjkim { 1188316303Sjkim return_ACPI_STATUS (Status); 1189316303Sjkim } 1190316303Sjkim 1191316303Sjkim Status = AcpiNsLoadTable (TableIndex, ParentNode); 1192316303Sjkim 1193316303Sjkim /* Execute any module-level code that was found in the table */ 1194316303Sjkim 1195316303Sjkim if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode) 1196316303Sjkim { 1197316303Sjkim AcpiNsExecModuleCodeList (); 1198316303Sjkim } 1199316303Sjkim 1200316303Sjkim /* 1201316303Sjkim * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is 1202316303Sjkim * responsible for discovering any new wake GPEs by running _PRW methods 1203316303Sjkim * that may have been loaded by this table. 1204316303Sjkim */ 1205316303Sjkim Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); 1206316303Sjkim if (ACPI_SUCCESS (Status)) 1207316303Sjkim { 1208316303Sjkim AcpiEvUpdateGpes (OwnerId); 1209316303Sjkim } 1210316303Sjkim 1211322877Sjkim /* Invoke table handler */ 1212316303Sjkim 1213322877Sjkim AcpiTbNotifyTable (ACPI_TABLE_EVENT_LOAD, Table); 1214316303Sjkim return_ACPI_STATUS (Status); 1215316303Sjkim} 1216316303Sjkim 1217316303Sjkim 1218316303Sjkim/******************************************************************************* 1219316303Sjkim * 1220316303Sjkim * FUNCTION: AcpiTbInstallAndLoadTable 1221316303Sjkim * 1222316303Sjkim * PARAMETERS: Address - Physical address of the table 1223316303Sjkim * Flags - Allocation flags of the table 1224316303Sjkim * Override - Whether override should be performed 1225316303Sjkim * TableIndex - Where table index is returned 1226316303Sjkim * 1227316303Sjkim * RETURN: Status 1228316303Sjkim * 1229316303Sjkim * DESCRIPTION: Install and load an ACPI table 1230316303Sjkim * 1231316303Sjkim ******************************************************************************/ 1232316303Sjkim 1233316303SjkimACPI_STATUS 1234316303SjkimAcpiTbInstallAndLoadTable ( 1235316303Sjkim ACPI_PHYSICAL_ADDRESS Address, 1236316303Sjkim UINT8 Flags, 1237316303Sjkim BOOLEAN Override, 1238316303Sjkim UINT32 *TableIndex) 1239316303Sjkim{ 1240316303Sjkim ACPI_STATUS Status; 1241316303Sjkim UINT32 i; 1242316303Sjkim 1243316303Sjkim 1244316303Sjkim ACPI_FUNCTION_TRACE (TbInstallAndLoadTable); 1245316303Sjkim 1246316303Sjkim 1247316303Sjkim /* Install the table and load it into the namespace */ 1248316303Sjkim 1249316303Sjkim Status = AcpiTbInstallStandardTable (Address, Flags, TRUE, 1250316303Sjkim Override, &i); 1251316303Sjkim if (ACPI_FAILURE (Status)) 1252316303Sjkim { 1253322877Sjkim goto Exit; 1254316303Sjkim } 1255316303Sjkim 1256316303Sjkim Status = AcpiTbLoadTable (i, AcpiGbl_RootNode); 1257316303Sjkim 1258322877SjkimExit: 1259316303Sjkim *TableIndex = i; 1260316303Sjkim return_ACPI_STATUS (Status); 1261316303Sjkim} 1262316303Sjkim 1263316303Sjkim 1264316303Sjkim/******************************************************************************* 1265316303Sjkim * 1266316303Sjkim * FUNCTION: AcpiTbUnloadTable 1267316303Sjkim * 1268316303Sjkim * PARAMETERS: TableIndex - Table index 1269316303Sjkim * 1270316303Sjkim * RETURN: Status 1271316303Sjkim * 1272316303Sjkim * DESCRIPTION: Unload an ACPI table 1273316303Sjkim * 1274316303Sjkim ******************************************************************************/ 1275316303Sjkim 1276316303SjkimACPI_STATUS 1277316303SjkimAcpiTbUnloadTable ( 1278316303Sjkim UINT32 TableIndex) 1279316303Sjkim{ 1280316303Sjkim ACPI_STATUS Status = AE_OK; 1281316303Sjkim ACPI_TABLE_HEADER *Table; 1282316303Sjkim 1283316303Sjkim 1284316303Sjkim ACPI_FUNCTION_TRACE (TbUnloadTable); 1285316303Sjkim 1286316303Sjkim 1287316303Sjkim /* Ensure the table is still loaded */ 1288316303Sjkim 1289316303Sjkim if (!AcpiTbIsTableLoaded (TableIndex)) 1290316303Sjkim { 1291316303Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 1292316303Sjkim } 1293316303Sjkim 1294322877Sjkim /* Invoke table handler */ 1295316303Sjkim 1296322877Sjkim Status = AcpiGetTableByIndex (TableIndex, &Table); 1297322877Sjkim if (ACPI_SUCCESS (Status)) 1298316303Sjkim { 1299322877Sjkim AcpiTbNotifyTable (ACPI_TABLE_EVENT_UNLOAD, Table); 1300316303Sjkim } 1301316303Sjkim 1302316303Sjkim /* Delete the portion of the namespace owned by this table */ 1303316303Sjkim 1304316303Sjkim Status = AcpiTbDeleteNamespaceByOwner (TableIndex); 1305316303Sjkim if (ACPI_FAILURE (Status)) 1306316303Sjkim { 1307316303Sjkim return_ACPI_STATUS (Status); 1308316303Sjkim } 1309316303Sjkim 1310316303Sjkim (void) AcpiTbReleaseOwnerId (TableIndex); 1311316303Sjkim AcpiTbSetTableLoadedFlag (TableIndex, FALSE); 1312316303Sjkim return_ACPI_STATUS (Status); 1313316303Sjkim} 1314322877Sjkim 1315322877Sjkim 1316322877Sjkim/******************************************************************************* 1317322877Sjkim * 1318322877Sjkim * FUNCTION: AcpiTbNotifyTable 1319322877Sjkim * 1320322877Sjkim * PARAMETERS: Event - Table event 1321322877Sjkim * Table - Validated table pointer 1322322877Sjkim * 1323322877Sjkim * RETURN: None 1324322877Sjkim * 1325322877Sjkim * DESCRIPTION: Notify a table event to the users. 1326322877Sjkim * 1327322877Sjkim ******************************************************************************/ 1328322877Sjkim 1329322877Sjkimvoid 1330322877SjkimAcpiTbNotifyTable ( 1331322877Sjkim UINT32 Event, 1332322877Sjkim void *Table) 1333322877Sjkim{ 1334322877Sjkim /* Invoke table handler if present */ 1335322877Sjkim 1336322877Sjkim if (AcpiGbl_TableHandler) 1337322877Sjkim { 1338322877Sjkim (void) AcpiGbl_TableHandler (Event, Table, 1339322877Sjkim AcpiGbl_TableHandlerContext); 1340322877Sjkim } 1341322877Sjkim} 1342