tbinstal.c revision 231844
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: tbinstal - ACPI table installation and removal 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8229989Sjkim * Copyright (C) 2000 - 2012, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 4467754Smsmith 4567754Smsmith#define __TBINSTAL_C__ 4667754Smsmith 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/actables.h> 5167754Smsmith 5267754Smsmith 5377424Smsmith#define _COMPONENT ACPI_TABLES 5491116Smsmith ACPI_MODULE_NAME ("tbinstal") 5567754Smsmith 5667754Smsmith 57167802Sjkim/****************************************************************************** 5867754Smsmith * 59167802Sjkim * FUNCTION: AcpiTbVerifyTable 6091116Smsmith * 61167802Sjkim * PARAMETERS: TableDesc - table 6291116Smsmith * 6391116Smsmith * RETURN: Status 6491116Smsmith * 65167802Sjkim * DESCRIPTION: this function is called to verify and map table 6691116Smsmith * 67167802Sjkim *****************************************************************************/ 6891116Smsmith 69167802SjkimACPI_STATUS 70167802SjkimAcpiTbVerifyTable ( 71167802Sjkim ACPI_TABLE_DESC *TableDesc) 7291116Smsmith{ 73167802Sjkim ACPI_STATUS Status = AE_OK; 7491116Smsmith 7591116Smsmith 76167802Sjkim ACPI_FUNCTION_TRACE (TbVerifyTable); 7791116Smsmith 7891116Smsmith 79167802Sjkim /* Map the table if necessary */ 80151937Sjkim 81167802Sjkim if (!TableDesc->Pointer) 8291116Smsmith { 83167802Sjkim if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == 84167802Sjkim ACPI_TABLE_ORIGIN_MAPPED) 85100966Siwasaki { 86193267Sjkim TableDesc->Pointer = AcpiOsMapMemory ( 87193267Sjkim TableDesc->Address, TableDesc->Length); 88100966Siwasaki } 89100966Siwasaki 90167802Sjkim if (!TableDesc->Pointer) 9191116Smsmith { 92167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 93167802Sjkim } 94167802Sjkim } 9591116Smsmith 96167802Sjkim /* FACS is the odd table, has no standard ACPI header and no checksum */ 9791116Smsmith 98167802Sjkim if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS)) 99167802Sjkim { 100167802Sjkim /* Always calculate checksum, ignore bad checksum if requested */ 10191116Smsmith 102167802Sjkim Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 10391116Smsmith } 10491116Smsmith 105167802Sjkim return_ACPI_STATUS (Status); 10691116Smsmith} 10791116Smsmith 10891116Smsmith 10991116Smsmith/******************************************************************************* 11091116Smsmith * 111167802Sjkim * FUNCTION: AcpiTbAddTable 11267754Smsmith * 113167802Sjkim * PARAMETERS: TableDesc - Table descriptor 114167802Sjkim * TableIndex - Where the table index is returned 11567754Smsmith * 11667754Smsmith * RETURN: Status 11767754Smsmith * 118193267Sjkim * DESCRIPTION: This function is called to add an ACPI table. It is used to 119193267Sjkim * dynamically load tables via the Load and LoadTable AML 120193267Sjkim * operators. 12167754Smsmith * 12267754Smsmith ******************************************************************************/ 12367754Smsmith 12467754SmsmithACPI_STATUS 125167802SjkimAcpiTbAddTable ( 126167802Sjkim ACPI_TABLE_DESC *TableDesc, 127193267Sjkim UINT32 *TableIndex) 12867754Smsmith{ 129193267Sjkim UINT32 i; 130167802Sjkim ACPI_STATUS Status = AE_OK; 13167754Smsmith 132151937Sjkim 133167802Sjkim ACPI_FUNCTION_TRACE (TbAddTable); 13467754Smsmith 13567754Smsmith 136167802Sjkim if (!TableDesc->Pointer) 137167802Sjkim { 138167802Sjkim Status = AcpiTbVerifyTable (TableDesc); 139167802Sjkim if (ACPI_FAILURE (Status) || !TableDesc->Pointer) 140167802Sjkim { 141167802Sjkim return_ACPI_STATUS (Status); 142167802Sjkim } 143167802Sjkim } 14467754Smsmith 145193267Sjkim /* 146222544Sjkim * Validate the incoming table signature. 147222544Sjkim * 148222544Sjkim * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 149222544Sjkim * 2) We added support for OEMx tables, signature "OEM". 150222544Sjkim * 3) Valid tables were encountered with a null signature, so we just 151222544Sjkim * gave up on validating the signature, (05/2008). 152222544Sjkim * 4) We encountered non-AML tables such as the MADT, which caused 153222544Sjkim * interpreter errors and kernel faults. So now, we once again allow 154222544Sjkim * only "SSDT", "OEMx", and now, also a null signature. (05/2011). 155193267Sjkim */ 156222544Sjkim if ((TableDesc->Pointer->Signature[0] != 0x00) && 157222544Sjkim (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) && 158222544Sjkim (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3))) 159222544Sjkim { 160222544Sjkim ACPI_ERROR ((AE_INFO, 161222544Sjkim "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx", 162222544Sjkim AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ? 163222544Sjkim TableDesc->Pointer->Signature : "????", 164222544Sjkim *(UINT32 *) TableDesc->Pointer->Signature)); 165167802Sjkim 166222544Sjkim return_ACPI_STATUS (AE_BAD_SIGNATURE); 167222544Sjkim } 168222544Sjkim 169167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 170167802Sjkim 171167802Sjkim /* Check if table is already registered */ 172167802Sjkim 173207344Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 174151937Sjkim { 175167802Sjkim if (!AcpiGbl_RootTableList.Tables[i].Pointer) 176167802Sjkim { 177167802Sjkim Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); 178193267Sjkim if (ACPI_FAILURE (Status) || 179193267Sjkim !AcpiGbl_RootTableList.Tables[i].Pointer) 180167802Sjkim { 181167802Sjkim continue; 182167802Sjkim } 183167802Sjkim } 184167802Sjkim 185193267Sjkim /* 186193267Sjkim * Check for a table match on the entire table length, 187193267Sjkim * not just the header. 188193267Sjkim */ 189193267Sjkim if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) 190193267Sjkim { 191193267Sjkim continue; 192193267Sjkim } 193193267Sjkim 194167802Sjkim if (ACPI_MEMCMP (TableDesc->Pointer, 195193267Sjkim AcpiGbl_RootTableList.Tables[i].Pointer, 196193267Sjkim AcpiGbl_RootTableList.Tables[i].Length)) 197167802Sjkim { 198167802Sjkim continue; 199167802Sjkim } 200167802Sjkim 201193267Sjkim /* 202193267Sjkim * Note: the current mechanism does not unregister a table if it is 203193267Sjkim * dynamically unloaded. The related namespace entries are deleted, 204193267Sjkim * but the table remains in the root table list. 205193267Sjkim * 206193267Sjkim * The assumption here is that the number of different tables that 207193267Sjkim * will be loaded is actually small, and there is minimal overhead 208193267Sjkim * in just keeping the table in case it is needed again. 209193267Sjkim * 210193267Sjkim * If this assumption changes in the future (perhaps on large 211193267Sjkim * machines with many table load/unload operations), tables will 212193267Sjkim * need to be unregistered when they are unloaded, and slots in the 213193267Sjkim * root table list should be reused when empty. 214193267Sjkim */ 215167802Sjkim 216193267Sjkim /* 217193267Sjkim * Table is already registered. 218193267Sjkim * We can delete the table that was passed as a parameter. 219193267Sjkim */ 220167802Sjkim AcpiTbDeleteTable (TableDesc); 221167802Sjkim *TableIndex = i; 222193267Sjkim 223193267Sjkim if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) 224193267Sjkim { 225193267Sjkim /* Table is still loaded, this is an error */ 226193267Sjkim 227193267Sjkim Status = AE_ALREADY_EXISTS; 228193267Sjkim goto Release; 229193267Sjkim } 230193267Sjkim else 231193267Sjkim { 232193267Sjkim /* Table was unloaded, allow it to be reloaded */ 233193267Sjkim 234193267Sjkim TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; 235193267Sjkim TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; 236193267Sjkim Status = AE_OK; 237193267Sjkim goto PrintHeader; 238193267Sjkim } 239151937Sjkim } 240151937Sjkim 241167802Sjkim /* 242193267Sjkim * ACPI Table Override: 243193267Sjkim * Allow the host to override dynamically loaded tables. 244231844Sjkim * NOTE: the table is fully mapped at this point, and the mapping will 245231844Sjkim * be deleted by TbTableOverride if the table is actually overridden. 246167802Sjkim */ 247231844Sjkim (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc); 248193267Sjkim 249193267Sjkim /* Add the table to the global root table list */ 250193267Sjkim 251167802Sjkim Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, 252167802Sjkim TableDesc->Length, TableDesc->Flags, TableIndex); 253100966Siwasaki if (ACPI_FAILURE (Status)) 254100966Siwasaki { 255167802Sjkim goto Release; 256100966Siwasaki } 25767754Smsmith 258193267SjkimPrintHeader: 259167802Sjkim AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 26067754Smsmith 261167802SjkimRelease: 26291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 26367754Smsmith return_ACPI_STATUS (Status); 26467754Smsmith} 26567754Smsmith 26667754Smsmith 26767754Smsmith/******************************************************************************* 26867754Smsmith * 269231844Sjkim * FUNCTION: AcpiTbTableOverride 270231844Sjkim * 271231844Sjkim * PARAMETERS: TableHeader - Header for the original table 272231844Sjkim * TableDesc - Table descriptor initialized for the 273231844Sjkim * original table. May or may not be mapped. 274231844Sjkim * 275231844Sjkim * RETURN: Pointer to the entire new table. NULL if table not overridden. 276231844Sjkim * If overridden, installs the new table within the input table 277231844Sjkim * descriptor. 278231844Sjkim * 279231844Sjkim * DESCRIPTION: Attempt table override by calling the OSL override functions. 280231844Sjkim * Note: If the table is overridden, then the entire new table 281231844Sjkim * is mapped and returned by this function. 282231844Sjkim * 283231844Sjkim ******************************************************************************/ 284231844Sjkim 285231844SjkimACPI_TABLE_HEADER * 286231844SjkimAcpiTbTableOverride ( 287231844Sjkim ACPI_TABLE_HEADER *TableHeader, 288231844Sjkim ACPI_TABLE_DESC *TableDesc) 289231844Sjkim{ 290231844Sjkim ACPI_STATUS Status; 291231844Sjkim ACPI_TABLE_HEADER *NewTable = NULL; 292231844Sjkim ACPI_PHYSICAL_ADDRESS NewAddress = 0; 293231844Sjkim UINT32 NewTableLength = 0; 294231844Sjkim UINT8 NewFlags; 295231844Sjkim char *OverrideType; 296231844Sjkim 297231844Sjkim 298231844Sjkim /* (1) Attempt logical override (returns a logical address) */ 299231844Sjkim 300231844Sjkim Status = AcpiOsTableOverride (TableHeader, &NewTable); 301231844Sjkim if (ACPI_SUCCESS (Status) && NewTable) 302231844Sjkim { 303231844Sjkim NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable); 304231844Sjkim NewTableLength = NewTable->Length; 305231844Sjkim NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE; 306231844Sjkim OverrideType = "Logical"; 307231844Sjkim goto FinishOverride; 308231844Sjkim } 309231844Sjkim 310231844Sjkim /* (2) Attempt physical override (returns a physical address) */ 311231844Sjkim 312231844Sjkim Status = AcpiOsPhysicalTableOverride (TableHeader, 313231844Sjkim &NewAddress, &NewTableLength); 314231844Sjkim if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength) 315231844Sjkim { 316231844Sjkim /* Map the entire new table */ 317231844Sjkim 318231844Sjkim NewTable = AcpiOsMapMemory (NewAddress, NewTableLength); 319231844Sjkim if (!NewTable) 320231844Sjkim { 321231844Sjkim ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 322231844Sjkim "%4.4s %p Attempted physical table override failed", 323231844Sjkim TableHeader->Signature, 324231844Sjkim ACPI_CAST_PTR (void, TableDesc->Address))); 325231844Sjkim return (NULL); 326231844Sjkim } 327231844Sjkim 328231844Sjkim OverrideType = "Physical"; 329231844Sjkim NewFlags = ACPI_TABLE_ORIGIN_MAPPED; 330231844Sjkim goto FinishOverride; 331231844Sjkim } 332231844Sjkim 333231844Sjkim return (NULL); /* There was no override */ 334231844Sjkim 335231844Sjkim 336231844SjkimFinishOverride: 337231844Sjkim 338231844Sjkim ACPI_INFO ((AE_INFO, 339231844Sjkim "%4.4s %p %s table override, new table: %p", 340231844Sjkim TableHeader->Signature, 341231844Sjkim ACPI_CAST_PTR (void, TableDesc->Address), 342231844Sjkim OverrideType, NewTable)); 343231844Sjkim 344231844Sjkim /* We can now unmap/delete the original table (if fully mapped) */ 345231844Sjkim 346231844Sjkim AcpiTbDeleteTable (TableDesc); 347231844Sjkim 348231844Sjkim /* Setup descriptor for the new table */ 349231844Sjkim 350231844Sjkim TableDesc->Address = NewAddress; 351231844Sjkim TableDesc->Pointer = NewTable; 352231844Sjkim TableDesc->Length = NewTableLength; 353231844Sjkim TableDesc->Flags = NewFlags; 354231844Sjkim 355231844Sjkim return (NewTable); 356231844Sjkim} 357231844Sjkim 358231844Sjkim 359231844Sjkim/******************************************************************************* 360231844Sjkim * 361167802Sjkim * FUNCTION: AcpiTbResizeRootTableList 36267754Smsmith * 363167802Sjkim * PARAMETERS: None 36467754Smsmith * 36567754Smsmith * RETURN: Status 36667754Smsmith * 367167802Sjkim * DESCRIPTION: Expand the size of global table array 36867754Smsmith * 36967754Smsmith ******************************************************************************/ 37067754Smsmith 37167754SmsmithACPI_STATUS 372167802SjkimAcpiTbResizeRootTableList ( 373167802Sjkim void) 37467754Smsmith{ 375167802Sjkim ACPI_TABLE_DESC *Tables; 37667754Smsmith 37767754Smsmith 378167802Sjkim ACPI_FUNCTION_TRACE (TbResizeRootTableList); 37967754Smsmith 38067754Smsmith 381167802Sjkim /* AllowResize flag is a parameter to AcpiInitializeTables */ 38267754Smsmith 383167802Sjkim if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 38467754Smsmith { 385167802Sjkim ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 386167802Sjkim return_ACPI_STATUS (AE_SUPPORT); 38767754Smsmith } 38867754Smsmith 389167802Sjkim /* Increase the Table Array size */ 390167802Sjkim 391167802Sjkim Tables = ACPI_ALLOCATE_ZEROED ( 392207344Sjkim ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount + 393193267Sjkim ACPI_ROOT_TABLE_SIZE_INCREMENT) * 394193267Sjkim sizeof (ACPI_TABLE_DESC)); 395167802Sjkim if (!Tables) 39667754Smsmith { 397167802Sjkim ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 398167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 39999146Siwasaki } 40091116Smsmith 401167802Sjkim /* Copy and free the previous table array */ 402167802Sjkim 403167802Sjkim if (AcpiGbl_RootTableList.Tables) 40499146Siwasaki { 405167802Sjkim ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, 406207344Sjkim (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC)); 407167802Sjkim 408167802Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 409167802Sjkim { 410167802Sjkim ACPI_FREE (AcpiGbl_RootTableList.Tables); 411167802Sjkim } 41299146Siwasaki } 41391116Smsmith 414167802Sjkim AcpiGbl_RootTableList.Tables = Tables; 415207344Sjkim AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT; 416167802Sjkim AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED; 41799146Siwasaki 418167802Sjkim return_ACPI_STATUS (AE_OK); 41967754Smsmith} 42067754Smsmith 42167754Smsmith 42267754Smsmith/******************************************************************************* 42367754Smsmith * 424167802Sjkim * FUNCTION: AcpiTbStoreTable 42567754Smsmith * 426167802Sjkim * PARAMETERS: Address - Table address 427167802Sjkim * Table - Table header 428167802Sjkim * Length - Table length 429167802Sjkim * Flags - flags 43067754Smsmith * 431167802Sjkim * RETURN: Status and table index. 43267754Smsmith * 433167802Sjkim * DESCRIPTION: Add an ACPI table to the global table list 43467754Smsmith * 43567754Smsmith ******************************************************************************/ 43667754Smsmith 43767754SmsmithACPI_STATUS 438167802SjkimAcpiTbStoreTable ( 439167802Sjkim ACPI_PHYSICAL_ADDRESS Address, 440167802Sjkim ACPI_TABLE_HEADER *Table, 441167802Sjkim UINT32 Length, 442167802Sjkim UINT8 Flags, 443193267Sjkim UINT32 *TableIndex) 44467754Smsmith{ 445207344Sjkim ACPI_STATUS Status; 446207344Sjkim ACPI_TABLE_DESC *NewTable; 44767754Smsmith 44867754Smsmith 449167802Sjkim /* Ensure that there is room for the table in the Root Table List */ 45067754Smsmith 451207344Sjkim if (AcpiGbl_RootTableList.CurrentTableCount >= 452207344Sjkim AcpiGbl_RootTableList.MaxTableCount) 453117521Snjl { 454167802Sjkim Status = AcpiTbResizeRootTableList(); 455167802Sjkim if (ACPI_FAILURE (Status)) 456167802Sjkim { 457167802Sjkim return (Status); 458167802Sjkim } 459117521Snjl } 460117521Snjl 461207344Sjkim NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; 462207344Sjkim 463167802Sjkim /* Initialize added table */ 464151937Sjkim 465207344Sjkim NewTable->Address = Address; 466207344Sjkim NewTable->Pointer = Table; 467207344Sjkim NewTable->Length = Length; 468207344Sjkim NewTable->OwnerId = 0; 469207344Sjkim NewTable->Flags = Flags; 470151937Sjkim 471207344Sjkim ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); 472151937Sjkim 473207344Sjkim *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; 474207344Sjkim AcpiGbl_RootTableList.CurrentTableCount++; 475207344Sjkim return (AE_OK); 476167802Sjkim} 47767754Smsmith 478123315Snjl 479167802Sjkim/******************************************************************************* 480167802Sjkim * 481167802Sjkim * FUNCTION: AcpiTbDeleteTable 482167802Sjkim * 483167802Sjkim * PARAMETERS: TableIndex - Table index 484167802Sjkim * 485167802Sjkim * RETURN: None 486167802Sjkim * 487167802Sjkim * DESCRIPTION: Delete one internal ACPI table 488167802Sjkim * 489167802Sjkim ******************************************************************************/ 490123315Snjl 491167802Sjkimvoid 492167802SjkimAcpiTbDeleteTable ( 493167802Sjkim ACPI_TABLE_DESC *TableDesc) 494167802Sjkim{ 495123315Snjl 496167802Sjkim /* Table must be mapped or allocated */ 497167802Sjkim 498167802Sjkim if (!TableDesc->Pointer) 499123315Snjl { 500167802Sjkim return; 501117521Snjl } 50267754Smsmith 503167802Sjkim switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 504167802Sjkim { 505167802Sjkim case ACPI_TABLE_ORIGIN_MAPPED: 506167802Sjkim AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); 507167802Sjkim break; 50867754Smsmith 509167802Sjkim case ACPI_TABLE_ORIGIN_ALLOCATED: 510167802Sjkim ACPI_FREE (TableDesc->Pointer); 511167802Sjkim break; 51267754Smsmith 513167802Sjkim default: 514167802Sjkim break; 51567754Smsmith } 51667754Smsmith 517167802Sjkim TableDesc->Pointer = NULL; 51867754Smsmith} 51967754Smsmith 52067754Smsmith 52167754Smsmith/******************************************************************************* 52267754Smsmith * 523167802Sjkim * FUNCTION: AcpiTbTerminate 52467754Smsmith * 525167802Sjkim * PARAMETERS: None 52667754Smsmith * 527167802Sjkim * RETURN: None 52867754Smsmith * 52967754Smsmith * DESCRIPTION: Delete all internal ACPI tables 53067754Smsmith * 53167754Smsmith ******************************************************************************/ 53267754Smsmith 53367754Smsmithvoid 534167802SjkimAcpiTbTerminate ( 535151937Sjkim void) 53667754Smsmith{ 537193267Sjkim UINT32 i; 53867754Smsmith 53967754Smsmith 540167802Sjkim ACPI_FUNCTION_TRACE (TbTerminate); 541167802Sjkim 542167802Sjkim 543167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 544167802Sjkim 545167802Sjkim /* Delete the individual tables */ 546167802Sjkim 547207344Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 548167802Sjkim { 549167802Sjkim AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); 550167802Sjkim } 551167802Sjkim 55267754Smsmith /* 553167802Sjkim * Delete the root table array if allocated locally. Array cannot be 554167802Sjkim * mapped, so we don't need to check for that flag. 55567754Smsmith */ 556167802Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 55767754Smsmith { 558167802Sjkim ACPI_FREE (AcpiGbl_RootTableList.Tables); 55967754Smsmith } 560167802Sjkim 561167802Sjkim AcpiGbl_RootTableList.Tables = NULL; 562167802Sjkim AcpiGbl_RootTableList.Flags = 0; 563207344Sjkim AcpiGbl_RootTableList.CurrentTableCount = 0; 564167802Sjkim 565167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 566167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 56767754Smsmith} 56867754Smsmith 56967754Smsmith 57067754Smsmith/******************************************************************************* 57167754Smsmith * 572167802Sjkim * FUNCTION: AcpiTbDeleteNamespaceByOwner 57367754Smsmith * 574167802Sjkim * PARAMETERS: TableIndex - Table index 57567754Smsmith * 576193267Sjkim * RETURN: Status 57767754Smsmith * 578167802Sjkim * DESCRIPTION: Delete all namespace objects created when this table was loaded. 57967754Smsmith * 58067754Smsmith ******************************************************************************/ 58167754Smsmith 582193267SjkimACPI_STATUS 583167802SjkimAcpiTbDeleteNamespaceByOwner ( 584193267Sjkim UINT32 TableIndex) 58567754Smsmith{ 586167802Sjkim ACPI_OWNER_ID OwnerId; 587193267Sjkim ACPI_STATUS Status; 58867754Smsmith 58967754Smsmith 590193267Sjkim ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 591193267Sjkim 592193267Sjkim 593193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 594193267Sjkim if (ACPI_FAILURE (Status)) 59567754Smsmith { 596193267Sjkim return_ACPI_STATUS (Status); 59767754Smsmith } 598193267Sjkim 599207344Sjkim if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 60091116Smsmith { 601193267Sjkim /* The table index does not exist */ 602193267Sjkim 603167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 604193267Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 60591116Smsmith } 60667754Smsmith 607193267Sjkim /* Get the owner ID for this table, used to delete namespace nodes */ 608193267Sjkim 609193267Sjkim OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 610167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 611193267Sjkim 612193267Sjkim /* 613193267Sjkim * Need to acquire the namespace writer lock to prevent interference 614193267Sjkim * with any concurrent namespace walks. The interpreter must be 615193267Sjkim * released during the deletion since the acquisition of the deletion 616193267Sjkim * lock may block, and also since the execution of a namespace walk 617193267Sjkim * must be allowed to use the interpreter. 618193267Sjkim */ 619193267Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 620193267Sjkim Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 621193267Sjkim 622167802Sjkim AcpiNsDeleteNamespaceByOwner (OwnerId); 623193267Sjkim if (ACPI_FAILURE (Status)) 624193267Sjkim { 625193267Sjkim return_ACPI_STATUS (Status); 626193267Sjkim } 627193267Sjkim 628193267Sjkim AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 629193267Sjkim 630193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 631193267Sjkim return_ACPI_STATUS (Status); 632167802Sjkim} 63367754Smsmith 63467754Smsmith 635167802Sjkim/******************************************************************************* 636167802Sjkim * 637167802Sjkim * FUNCTION: AcpiTbAllocateOwnerId 638167802Sjkim * 639167802Sjkim * PARAMETERS: TableIndex - Table index 640167802Sjkim * 641167802Sjkim * RETURN: Status 642167802Sjkim * 643167802Sjkim * DESCRIPTION: Allocates OwnerId in TableDesc 644167802Sjkim * 645167802Sjkim ******************************************************************************/ 64667754Smsmith 647167802SjkimACPI_STATUS 648167802SjkimAcpiTbAllocateOwnerId ( 649193267Sjkim UINT32 TableIndex) 650167802Sjkim{ 651167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 65267754Smsmith 65367754Smsmith 654167802Sjkim ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 65567754Smsmith 65667754Smsmith 657167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 658207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 65967754Smsmith { 660167802Sjkim Status = AcpiUtAllocateOwnerId 661167802Sjkim (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 66267754Smsmith } 66367754Smsmith 664117521Snjl (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 665167802Sjkim return_ACPI_STATUS (Status); 66667754Smsmith} 66767754Smsmith 66867754Smsmith 66967754Smsmith/******************************************************************************* 67067754Smsmith * 671167802Sjkim * FUNCTION: AcpiTbReleaseOwnerId 67267754Smsmith * 673167802Sjkim * PARAMETERS: TableIndex - Table index 67467754Smsmith * 675167802Sjkim * RETURN: Status 67667754Smsmith * 677167802Sjkim * DESCRIPTION: Releases OwnerId in TableDesc 67867754Smsmith * 67967754Smsmith ******************************************************************************/ 68067754Smsmith 681167802SjkimACPI_STATUS 682167802SjkimAcpiTbReleaseOwnerId ( 683193267Sjkim UINT32 TableIndex) 68467754Smsmith{ 685167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 68667754Smsmith 687117521Snjl 688167802Sjkim ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 68967754Smsmith 690117521Snjl 691167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 692207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 69367754Smsmith { 694193267Sjkim AcpiUtReleaseOwnerId ( 695193267Sjkim &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 696167802Sjkim Status = AE_OK; 697167802Sjkim } 69867754Smsmith 699167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 700167802Sjkim return_ACPI_STATUS (Status); 70167754Smsmith} 70267754Smsmith 70367754Smsmith 70467754Smsmith/******************************************************************************* 70567754Smsmith * 706167802Sjkim * FUNCTION: AcpiTbGetOwnerId 70767754Smsmith * 708167802Sjkim * PARAMETERS: TableIndex - Table index 709167802Sjkim * OwnerId - Where the table OwnerId is returned 71067754Smsmith * 711167802Sjkim * RETURN: Status 71267754Smsmith * 713167802Sjkim * DESCRIPTION: returns OwnerId for the ACPI table 71467754Smsmith * 71567754Smsmith ******************************************************************************/ 71667754Smsmith 717167802SjkimACPI_STATUS 718167802SjkimAcpiTbGetOwnerId ( 719193267Sjkim UINT32 TableIndex, 720167802Sjkim ACPI_OWNER_ID *OwnerId) 72167754Smsmith{ 722167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 72367754Smsmith 72467754Smsmith 725167802Sjkim ACPI_FUNCTION_TRACE (TbGetOwnerId); 72667754Smsmith 72767754Smsmith 728167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 729207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 73067754Smsmith { 731167802Sjkim *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 732167802Sjkim Status = AE_OK; 73367754Smsmith } 73467754Smsmith 735167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 736167802Sjkim return_ACPI_STATUS (Status); 737167802Sjkim} 73867754Smsmith 73967754Smsmith 740167802Sjkim/******************************************************************************* 741167802Sjkim * 742167802Sjkim * FUNCTION: AcpiTbIsTableLoaded 743167802Sjkim * 744167802Sjkim * PARAMETERS: TableIndex - Table index 745167802Sjkim * 746167802Sjkim * RETURN: Table Loaded Flag 747167802Sjkim * 748167802Sjkim ******************************************************************************/ 749117521Snjl 750167802SjkimBOOLEAN 751167802SjkimAcpiTbIsTableLoaded ( 752193267Sjkim UINT32 TableIndex) 753167802Sjkim{ 754167802Sjkim BOOLEAN IsLoaded = FALSE; 755167802Sjkim 756167802Sjkim 757167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 758207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 75967754Smsmith { 760167802Sjkim IsLoaded = (BOOLEAN) 761193267Sjkim (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 762193267Sjkim ACPI_TABLE_IS_LOADED); 76367754Smsmith } 76467754Smsmith 765167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 766167802Sjkim return (IsLoaded); 767167802Sjkim} 76867754Smsmith 76967754Smsmith 770167802Sjkim/******************************************************************************* 771167802Sjkim * 772167802Sjkim * FUNCTION: AcpiTbSetTableLoadedFlag 773167802Sjkim * 774167802Sjkim * PARAMETERS: TableIndex - Table index 775167802Sjkim * IsLoaded - TRUE if table is loaded, FALSE otherwise 776167802Sjkim * 777167802Sjkim * RETURN: None 778167802Sjkim * 779167802Sjkim * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 780167802Sjkim * 781167802Sjkim ******************************************************************************/ 78267754Smsmith 783167802Sjkimvoid 784167802SjkimAcpiTbSetTableLoadedFlag ( 785193267Sjkim UINT32 TableIndex, 786167802Sjkim BOOLEAN IsLoaded) 787167802Sjkim{ 78867754Smsmith 789167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 790207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 791167802Sjkim { 792167802Sjkim if (IsLoaded) 793167802Sjkim { 794193267Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 795193267Sjkim ACPI_TABLE_IS_LOADED; 796167802Sjkim } 797167802Sjkim else 798167802Sjkim { 799193267Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 800193267Sjkim ~ACPI_TABLE_IS_LOADED; 801167802Sjkim } 802167802Sjkim } 80367754Smsmith 804167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 80567754Smsmith} 80667754Smsmith 807