tbinstal.c revision 245582
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: tbinstal - ACPI table installation and removal 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, 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 { 160238381Sjkim ACPI_BIOS_ERROR ((AE_INFO, 161238381Sjkim "Table has invalid signature [%4.4s] (0x%8.8X), " 162238381Sjkim "must be SSDT or OEMx", 163222544Sjkim AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ? 164222544Sjkim TableDesc->Pointer->Signature : "????", 165222544Sjkim *(UINT32 *) TableDesc->Pointer->Signature)); 166167802Sjkim 167222544Sjkim return_ACPI_STATUS (AE_BAD_SIGNATURE); 168222544Sjkim } 169222544Sjkim 170167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 171167802Sjkim 172167802Sjkim /* Check if table is already registered */ 173167802Sjkim 174207344Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 175151937Sjkim { 176167802Sjkim if (!AcpiGbl_RootTableList.Tables[i].Pointer) 177167802Sjkim { 178167802Sjkim Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); 179193267Sjkim if (ACPI_FAILURE (Status) || 180193267Sjkim !AcpiGbl_RootTableList.Tables[i].Pointer) 181167802Sjkim { 182167802Sjkim continue; 183167802Sjkim } 184167802Sjkim } 185167802Sjkim 186193267Sjkim /* 187193267Sjkim * Check for a table match on the entire table length, 188193267Sjkim * not just the header. 189193267Sjkim */ 190193267Sjkim if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) 191193267Sjkim { 192193267Sjkim continue; 193193267Sjkim } 194193267Sjkim 195167802Sjkim if (ACPI_MEMCMP (TableDesc->Pointer, 196193267Sjkim AcpiGbl_RootTableList.Tables[i].Pointer, 197193267Sjkim AcpiGbl_RootTableList.Tables[i].Length)) 198167802Sjkim { 199167802Sjkim continue; 200167802Sjkim } 201167802Sjkim 202193267Sjkim /* 203193267Sjkim * Note: the current mechanism does not unregister a table if it is 204193267Sjkim * dynamically unloaded. The related namespace entries are deleted, 205193267Sjkim * but the table remains in the root table list. 206193267Sjkim * 207193267Sjkim * The assumption here is that the number of different tables that 208193267Sjkim * will be loaded is actually small, and there is minimal overhead 209193267Sjkim * in just keeping the table in case it is needed again. 210193267Sjkim * 211193267Sjkim * If this assumption changes in the future (perhaps on large 212193267Sjkim * machines with many table load/unload operations), tables will 213193267Sjkim * need to be unregistered when they are unloaded, and slots in the 214193267Sjkim * root table list should be reused when empty. 215193267Sjkim */ 216167802Sjkim 217193267Sjkim /* 218193267Sjkim * Table is already registered. 219193267Sjkim * We can delete the table that was passed as a parameter. 220193267Sjkim */ 221167802Sjkim AcpiTbDeleteTable (TableDesc); 222167802Sjkim *TableIndex = i; 223193267Sjkim 224193267Sjkim if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) 225193267Sjkim { 226193267Sjkim /* Table is still loaded, this is an error */ 227193267Sjkim 228193267Sjkim Status = AE_ALREADY_EXISTS; 229193267Sjkim goto Release; 230193267Sjkim } 231193267Sjkim else 232193267Sjkim { 233193267Sjkim /* Table was unloaded, allow it to be reloaded */ 234193267Sjkim 235193267Sjkim TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; 236193267Sjkim TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; 237193267Sjkim Status = AE_OK; 238193267Sjkim goto PrintHeader; 239193267Sjkim } 240151937Sjkim } 241151937Sjkim 242167802Sjkim /* 243193267Sjkim * ACPI Table Override: 244193267Sjkim * Allow the host to override dynamically loaded tables. 245231844Sjkim * NOTE: the table is fully mapped at this point, and the mapping will 246231844Sjkim * be deleted by TbTableOverride if the table is actually overridden. 247167802Sjkim */ 248231844Sjkim (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc); 249193267Sjkim 250193267Sjkim /* Add the table to the global root table list */ 251193267Sjkim 252167802Sjkim Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, 253167802Sjkim TableDesc->Length, TableDesc->Flags, TableIndex); 254100966Siwasaki if (ACPI_FAILURE (Status)) 255100966Siwasaki { 256167802Sjkim goto Release; 257100966Siwasaki } 25867754Smsmith 259193267SjkimPrintHeader: 260167802Sjkim AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 26167754Smsmith 262167802SjkimRelease: 26391116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 26467754Smsmith return_ACPI_STATUS (Status); 26567754Smsmith} 26667754Smsmith 26767754Smsmith 26867754Smsmith/******************************************************************************* 26967754Smsmith * 270231844Sjkim * FUNCTION: AcpiTbTableOverride 271231844Sjkim * 272231844Sjkim * PARAMETERS: TableHeader - Header for the original table 273231844Sjkim * TableDesc - Table descriptor initialized for the 274231844Sjkim * original table. May or may not be mapped. 275231844Sjkim * 276231844Sjkim * RETURN: Pointer to the entire new table. NULL if table not overridden. 277231844Sjkim * If overridden, installs the new table within the input table 278231844Sjkim * descriptor. 279231844Sjkim * 280231844Sjkim * DESCRIPTION: Attempt table override by calling the OSL override functions. 281231844Sjkim * Note: If the table is overridden, then the entire new table 282231844Sjkim * is mapped and returned by this function. 283231844Sjkim * 284231844Sjkim ******************************************************************************/ 285231844Sjkim 286231844SjkimACPI_TABLE_HEADER * 287231844SjkimAcpiTbTableOverride ( 288231844Sjkim ACPI_TABLE_HEADER *TableHeader, 289231844Sjkim ACPI_TABLE_DESC *TableDesc) 290231844Sjkim{ 291231844Sjkim ACPI_STATUS Status; 292231844Sjkim ACPI_TABLE_HEADER *NewTable = NULL; 293231844Sjkim ACPI_PHYSICAL_ADDRESS NewAddress = 0; 294231844Sjkim UINT32 NewTableLength = 0; 295231844Sjkim UINT8 NewFlags; 296231844Sjkim char *OverrideType; 297231844Sjkim 298231844Sjkim 299231844Sjkim /* (1) Attempt logical override (returns a logical address) */ 300231844Sjkim 301231844Sjkim Status = AcpiOsTableOverride (TableHeader, &NewTable); 302231844Sjkim if (ACPI_SUCCESS (Status) && NewTable) 303231844Sjkim { 304231844Sjkim NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable); 305231844Sjkim NewTableLength = NewTable->Length; 306231844Sjkim NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE; 307231844Sjkim OverrideType = "Logical"; 308231844Sjkim goto FinishOverride; 309231844Sjkim } 310231844Sjkim 311231844Sjkim /* (2) Attempt physical override (returns a physical address) */ 312231844Sjkim 313231844Sjkim Status = AcpiOsPhysicalTableOverride (TableHeader, 314231844Sjkim &NewAddress, &NewTableLength); 315231844Sjkim if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength) 316231844Sjkim { 317231844Sjkim /* Map the entire new table */ 318231844Sjkim 319231844Sjkim NewTable = AcpiOsMapMemory (NewAddress, NewTableLength); 320231844Sjkim if (!NewTable) 321231844Sjkim { 322231844Sjkim ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 323231844Sjkim "%4.4s %p Attempted physical table override failed", 324231844Sjkim TableHeader->Signature, 325231844Sjkim ACPI_CAST_PTR (void, TableDesc->Address))); 326231844Sjkim return (NULL); 327231844Sjkim } 328231844Sjkim 329231844Sjkim OverrideType = "Physical"; 330231844Sjkim NewFlags = ACPI_TABLE_ORIGIN_MAPPED; 331231844Sjkim goto FinishOverride; 332231844Sjkim } 333231844Sjkim 334231844Sjkim return (NULL); /* There was no override */ 335231844Sjkim 336231844Sjkim 337231844SjkimFinishOverride: 338231844Sjkim 339231844Sjkim ACPI_INFO ((AE_INFO, 340231844Sjkim "%4.4s %p %s table override, new table: %p", 341231844Sjkim TableHeader->Signature, 342231844Sjkim ACPI_CAST_PTR (void, TableDesc->Address), 343231844Sjkim OverrideType, NewTable)); 344231844Sjkim 345231844Sjkim /* We can now unmap/delete the original table (if fully mapped) */ 346231844Sjkim 347231844Sjkim AcpiTbDeleteTable (TableDesc); 348231844Sjkim 349231844Sjkim /* Setup descriptor for the new table */ 350231844Sjkim 351231844Sjkim TableDesc->Address = NewAddress; 352231844Sjkim TableDesc->Pointer = NewTable; 353231844Sjkim TableDesc->Length = NewTableLength; 354231844Sjkim TableDesc->Flags = NewFlags; 355231844Sjkim 356231844Sjkim return (NewTable); 357231844Sjkim} 358231844Sjkim 359231844Sjkim 360231844Sjkim/******************************************************************************* 361231844Sjkim * 362167802Sjkim * FUNCTION: AcpiTbResizeRootTableList 36367754Smsmith * 364167802Sjkim * PARAMETERS: None 36567754Smsmith * 36667754Smsmith * RETURN: Status 36767754Smsmith * 368167802Sjkim * DESCRIPTION: Expand the size of global table array 36967754Smsmith * 37067754Smsmith ******************************************************************************/ 37167754Smsmith 37267754SmsmithACPI_STATUS 373167802SjkimAcpiTbResizeRootTableList ( 374167802Sjkim void) 37567754Smsmith{ 376167802Sjkim ACPI_TABLE_DESC *Tables; 377240716Sjkim UINT32 TableCount; 37867754Smsmith 37967754Smsmith 380167802Sjkim ACPI_FUNCTION_TRACE (TbResizeRootTableList); 38167754Smsmith 38267754Smsmith 383167802Sjkim /* AllowResize flag is a parameter to AcpiInitializeTables */ 38467754Smsmith 385167802Sjkim if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 38667754Smsmith { 387167802Sjkim ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 388167802Sjkim return_ACPI_STATUS (AE_SUPPORT); 38967754Smsmith } 39067754Smsmith 391167802Sjkim /* Increase the Table Array size */ 392167802Sjkim 393240716Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 394240716Sjkim { 395240716Sjkim TableCount = AcpiGbl_RootTableList.MaxTableCount; 396240716Sjkim } 397240716Sjkim else 398240716Sjkim { 399240716Sjkim TableCount = AcpiGbl_RootTableList.CurrentTableCount; 400240716Sjkim } 401240716Sjkim 402167802Sjkim Tables = ACPI_ALLOCATE_ZEROED ( 403240716Sjkim ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) * 404193267Sjkim sizeof (ACPI_TABLE_DESC)); 405167802Sjkim if (!Tables) 40667754Smsmith { 407167802Sjkim ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 408167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 40999146Siwasaki } 41091116Smsmith 411167802Sjkim /* Copy and free the previous table array */ 412167802Sjkim 413167802Sjkim if (AcpiGbl_RootTableList.Tables) 41499146Siwasaki { 415167802Sjkim ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, 416240716Sjkim (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC)); 417167802Sjkim 418167802Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 419167802Sjkim { 420167802Sjkim ACPI_FREE (AcpiGbl_RootTableList.Tables); 421167802Sjkim } 42299146Siwasaki } 42391116Smsmith 424167802Sjkim AcpiGbl_RootTableList.Tables = Tables; 425240716Sjkim AcpiGbl_RootTableList.MaxTableCount = 426240716Sjkim TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; 427240716Sjkim AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 42899146Siwasaki 429167802Sjkim return_ACPI_STATUS (AE_OK); 43067754Smsmith} 43167754Smsmith 43267754Smsmith 43367754Smsmith/******************************************************************************* 43467754Smsmith * 435167802Sjkim * FUNCTION: AcpiTbStoreTable 43667754Smsmith * 437167802Sjkim * PARAMETERS: Address - Table address 438167802Sjkim * Table - Table header 439167802Sjkim * Length - Table length 440167802Sjkim * Flags - flags 44167754Smsmith * 442167802Sjkim * RETURN: Status and table index. 44367754Smsmith * 444167802Sjkim * DESCRIPTION: Add an ACPI table to the global table list 44567754Smsmith * 44667754Smsmith ******************************************************************************/ 44767754Smsmith 44867754SmsmithACPI_STATUS 449167802SjkimAcpiTbStoreTable ( 450167802Sjkim ACPI_PHYSICAL_ADDRESS Address, 451167802Sjkim ACPI_TABLE_HEADER *Table, 452167802Sjkim UINT32 Length, 453167802Sjkim UINT8 Flags, 454193267Sjkim UINT32 *TableIndex) 45567754Smsmith{ 456207344Sjkim ACPI_STATUS Status; 457207344Sjkim ACPI_TABLE_DESC *NewTable; 45867754Smsmith 45967754Smsmith 460167802Sjkim /* Ensure that there is room for the table in the Root Table List */ 46167754Smsmith 462207344Sjkim if (AcpiGbl_RootTableList.CurrentTableCount >= 463207344Sjkim AcpiGbl_RootTableList.MaxTableCount) 464117521Snjl { 465167802Sjkim Status = AcpiTbResizeRootTableList(); 466167802Sjkim if (ACPI_FAILURE (Status)) 467167802Sjkim { 468167802Sjkim return (Status); 469167802Sjkim } 470117521Snjl } 471117521Snjl 472207344Sjkim NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; 473207344Sjkim 474167802Sjkim /* Initialize added table */ 475151937Sjkim 476207344Sjkim NewTable->Address = Address; 477207344Sjkim NewTable->Pointer = Table; 478207344Sjkim NewTable->Length = Length; 479207344Sjkim NewTable->OwnerId = 0; 480207344Sjkim NewTable->Flags = Flags; 481151937Sjkim 482207344Sjkim ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); 483151937Sjkim 484207344Sjkim *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; 485207344Sjkim AcpiGbl_RootTableList.CurrentTableCount++; 486207344Sjkim return (AE_OK); 487167802Sjkim} 48867754Smsmith 489123315Snjl 490167802Sjkim/******************************************************************************* 491167802Sjkim * 492167802Sjkim * FUNCTION: AcpiTbDeleteTable 493167802Sjkim * 494167802Sjkim * PARAMETERS: TableIndex - Table index 495167802Sjkim * 496167802Sjkim * RETURN: None 497167802Sjkim * 498167802Sjkim * DESCRIPTION: Delete one internal ACPI table 499167802Sjkim * 500167802Sjkim ******************************************************************************/ 501123315Snjl 502167802Sjkimvoid 503167802SjkimAcpiTbDeleteTable ( 504167802Sjkim ACPI_TABLE_DESC *TableDesc) 505167802Sjkim{ 506123315Snjl 507167802Sjkim /* Table must be mapped or allocated */ 508167802Sjkim 509167802Sjkim if (!TableDesc->Pointer) 510123315Snjl { 511167802Sjkim return; 512117521Snjl } 51367754Smsmith 514167802Sjkim switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 515167802Sjkim { 516167802Sjkim case ACPI_TABLE_ORIGIN_MAPPED: 517167802Sjkim AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); 518167802Sjkim break; 51967754Smsmith 520167802Sjkim case ACPI_TABLE_ORIGIN_ALLOCATED: 521167802Sjkim ACPI_FREE (TableDesc->Pointer); 522167802Sjkim break; 52367754Smsmith 524233250Sjkim /* Not mapped or allocated, there is nothing we can do */ 525233250Sjkim 526167802Sjkim default: 527233250Sjkim return; 52867754Smsmith } 52967754Smsmith 530167802Sjkim TableDesc->Pointer = NULL; 53167754Smsmith} 53267754Smsmith 53367754Smsmith 53467754Smsmith/******************************************************************************* 53567754Smsmith * 536167802Sjkim * FUNCTION: AcpiTbTerminate 53767754Smsmith * 538167802Sjkim * PARAMETERS: None 53967754Smsmith * 540167802Sjkim * RETURN: None 54167754Smsmith * 54267754Smsmith * DESCRIPTION: Delete all internal ACPI tables 54367754Smsmith * 54467754Smsmith ******************************************************************************/ 54567754Smsmith 54667754Smsmithvoid 547167802SjkimAcpiTbTerminate ( 548151937Sjkim void) 54967754Smsmith{ 550193267Sjkim UINT32 i; 55167754Smsmith 55267754Smsmith 553167802Sjkim ACPI_FUNCTION_TRACE (TbTerminate); 554167802Sjkim 555167802Sjkim 556167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 557167802Sjkim 558167802Sjkim /* Delete the individual tables */ 559167802Sjkim 560207344Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 561167802Sjkim { 562167802Sjkim AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); 563167802Sjkim } 564167802Sjkim 56567754Smsmith /* 566167802Sjkim * Delete the root table array if allocated locally. Array cannot be 567167802Sjkim * mapped, so we don't need to check for that flag. 56867754Smsmith */ 569167802Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 57067754Smsmith { 571167802Sjkim ACPI_FREE (AcpiGbl_RootTableList.Tables); 57267754Smsmith } 573167802Sjkim 574167802Sjkim AcpiGbl_RootTableList.Tables = NULL; 575167802Sjkim AcpiGbl_RootTableList.Flags = 0; 576207344Sjkim AcpiGbl_RootTableList.CurrentTableCount = 0; 577167802Sjkim 578167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 579167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 580241973Sjkim 581241973Sjkim return_VOID; 58267754Smsmith} 58367754Smsmith 58467754Smsmith 58567754Smsmith/******************************************************************************* 58667754Smsmith * 587167802Sjkim * FUNCTION: AcpiTbDeleteNamespaceByOwner 58867754Smsmith * 589167802Sjkim * PARAMETERS: TableIndex - Table index 59067754Smsmith * 591193267Sjkim * RETURN: Status 59267754Smsmith * 593167802Sjkim * DESCRIPTION: Delete all namespace objects created when this table was loaded. 59467754Smsmith * 59567754Smsmith ******************************************************************************/ 59667754Smsmith 597193267SjkimACPI_STATUS 598167802SjkimAcpiTbDeleteNamespaceByOwner ( 599193267Sjkim UINT32 TableIndex) 60067754Smsmith{ 601167802Sjkim ACPI_OWNER_ID OwnerId; 602193267Sjkim ACPI_STATUS Status; 60367754Smsmith 60467754Smsmith 605193267Sjkim ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 606193267Sjkim 607193267Sjkim 608193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 609193267Sjkim if (ACPI_FAILURE (Status)) 61067754Smsmith { 611193267Sjkim return_ACPI_STATUS (Status); 61267754Smsmith } 613193267Sjkim 614207344Sjkim if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 61591116Smsmith { 616193267Sjkim /* The table index does not exist */ 617193267Sjkim 618167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 619193267Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 62091116Smsmith } 62167754Smsmith 622193267Sjkim /* Get the owner ID for this table, used to delete namespace nodes */ 623193267Sjkim 624193267Sjkim OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 625167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 626193267Sjkim 627193267Sjkim /* 628193267Sjkim * Need to acquire the namespace writer lock to prevent interference 629193267Sjkim * with any concurrent namespace walks. The interpreter must be 630193267Sjkim * released during the deletion since the acquisition of the deletion 631193267Sjkim * lock may block, and also since the execution of a namespace walk 632193267Sjkim * must be allowed to use the interpreter. 633193267Sjkim */ 634193267Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 635193267Sjkim Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 636193267Sjkim 637167802Sjkim AcpiNsDeleteNamespaceByOwner (OwnerId); 638193267Sjkim if (ACPI_FAILURE (Status)) 639193267Sjkim { 640193267Sjkim return_ACPI_STATUS (Status); 641193267Sjkim } 642193267Sjkim 643193267Sjkim AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 644193267Sjkim 645193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 646193267Sjkim return_ACPI_STATUS (Status); 647167802Sjkim} 64867754Smsmith 64967754Smsmith 650167802Sjkim/******************************************************************************* 651167802Sjkim * 652167802Sjkim * FUNCTION: AcpiTbAllocateOwnerId 653167802Sjkim * 654167802Sjkim * PARAMETERS: TableIndex - Table index 655167802Sjkim * 656167802Sjkim * RETURN: Status 657167802Sjkim * 658167802Sjkim * DESCRIPTION: Allocates OwnerId in TableDesc 659167802Sjkim * 660167802Sjkim ******************************************************************************/ 66167754Smsmith 662167802SjkimACPI_STATUS 663167802SjkimAcpiTbAllocateOwnerId ( 664193267Sjkim UINT32 TableIndex) 665167802Sjkim{ 666167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 66767754Smsmith 66867754Smsmith 669167802Sjkim ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 67067754Smsmith 67167754Smsmith 672167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 673207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 67467754Smsmith { 675167802Sjkim Status = AcpiUtAllocateOwnerId 676167802Sjkim (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 67767754Smsmith } 67867754Smsmith 679117521Snjl (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 680167802Sjkim return_ACPI_STATUS (Status); 68167754Smsmith} 68267754Smsmith 68367754Smsmith 68467754Smsmith/******************************************************************************* 68567754Smsmith * 686167802Sjkim * FUNCTION: AcpiTbReleaseOwnerId 68767754Smsmith * 688167802Sjkim * PARAMETERS: TableIndex - Table index 68967754Smsmith * 690167802Sjkim * RETURN: Status 69167754Smsmith * 692167802Sjkim * DESCRIPTION: Releases OwnerId in TableDesc 69367754Smsmith * 69467754Smsmith ******************************************************************************/ 69567754Smsmith 696167802SjkimACPI_STATUS 697167802SjkimAcpiTbReleaseOwnerId ( 698193267Sjkim UINT32 TableIndex) 69967754Smsmith{ 700167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 70167754Smsmith 702117521Snjl 703167802Sjkim ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 70467754Smsmith 705117521Snjl 706167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 707207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 70867754Smsmith { 709193267Sjkim AcpiUtReleaseOwnerId ( 710193267Sjkim &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 711167802Sjkim Status = AE_OK; 712167802Sjkim } 71367754Smsmith 714167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 715167802Sjkim return_ACPI_STATUS (Status); 71667754Smsmith} 71767754Smsmith 71867754Smsmith 71967754Smsmith/******************************************************************************* 72067754Smsmith * 721167802Sjkim * FUNCTION: AcpiTbGetOwnerId 72267754Smsmith * 723167802Sjkim * PARAMETERS: TableIndex - Table index 724167802Sjkim * OwnerId - Where the table OwnerId is returned 72567754Smsmith * 726167802Sjkim * RETURN: Status 72767754Smsmith * 728167802Sjkim * DESCRIPTION: returns OwnerId for the ACPI table 72967754Smsmith * 73067754Smsmith ******************************************************************************/ 73167754Smsmith 732167802SjkimACPI_STATUS 733167802SjkimAcpiTbGetOwnerId ( 734193267Sjkim UINT32 TableIndex, 735167802Sjkim ACPI_OWNER_ID *OwnerId) 73667754Smsmith{ 737167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 73867754Smsmith 73967754Smsmith 740167802Sjkim ACPI_FUNCTION_TRACE (TbGetOwnerId); 74167754Smsmith 74267754Smsmith 743167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 744207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 74567754Smsmith { 746167802Sjkim *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 747167802Sjkim Status = AE_OK; 74867754Smsmith } 74967754Smsmith 750167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 751167802Sjkim return_ACPI_STATUS (Status); 752167802Sjkim} 75367754Smsmith 75467754Smsmith 755167802Sjkim/******************************************************************************* 756167802Sjkim * 757167802Sjkim * FUNCTION: AcpiTbIsTableLoaded 758167802Sjkim * 759167802Sjkim * PARAMETERS: TableIndex - Table index 760167802Sjkim * 761167802Sjkim * RETURN: Table Loaded Flag 762167802Sjkim * 763167802Sjkim ******************************************************************************/ 764117521Snjl 765167802SjkimBOOLEAN 766167802SjkimAcpiTbIsTableLoaded ( 767193267Sjkim UINT32 TableIndex) 768167802Sjkim{ 769167802Sjkim BOOLEAN IsLoaded = FALSE; 770167802Sjkim 771167802Sjkim 772167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 773207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 77467754Smsmith { 775167802Sjkim IsLoaded = (BOOLEAN) 776193267Sjkim (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 777193267Sjkim ACPI_TABLE_IS_LOADED); 77867754Smsmith } 77967754Smsmith 780167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 781167802Sjkim return (IsLoaded); 782167802Sjkim} 78367754Smsmith 78467754Smsmith 785167802Sjkim/******************************************************************************* 786167802Sjkim * 787167802Sjkim * FUNCTION: AcpiTbSetTableLoadedFlag 788167802Sjkim * 789167802Sjkim * PARAMETERS: TableIndex - Table index 790167802Sjkim * IsLoaded - TRUE if table is loaded, FALSE otherwise 791167802Sjkim * 792167802Sjkim * RETURN: None 793167802Sjkim * 794167802Sjkim * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 795167802Sjkim * 796167802Sjkim ******************************************************************************/ 79767754Smsmith 798167802Sjkimvoid 799167802SjkimAcpiTbSetTableLoadedFlag ( 800193267Sjkim UINT32 TableIndex, 801167802Sjkim BOOLEAN IsLoaded) 802167802Sjkim{ 80367754Smsmith 804167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 805207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 806167802Sjkim { 807167802Sjkim if (IsLoaded) 808167802Sjkim { 809193267Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 810193267Sjkim ACPI_TABLE_IS_LOADED; 811167802Sjkim } 812167802Sjkim else 813167802Sjkim { 814193267Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 815193267Sjkim ~ACPI_TABLE_IS_LOADED; 816167802Sjkim } 817167802Sjkim } 81867754Smsmith 819167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 82067754Smsmith} 821