tbinstal.c revision 250838
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", 163250838Sjkim AcpiUtValidAcpiName (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: 517250838Sjkim 518167802Sjkim AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); 519167802Sjkim break; 52067754Smsmith 521167802Sjkim case ACPI_TABLE_ORIGIN_ALLOCATED: 522250838Sjkim 523167802Sjkim ACPI_FREE (TableDesc->Pointer); 524167802Sjkim break; 52567754Smsmith 526233250Sjkim /* Not mapped or allocated, there is nothing we can do */ 527233250Sjkim 528167802Sjkim default: 529250838Sjkim 530233250Sjkim return; 53167754Smsmith } 53267754Smsmith 533167802Sjkim TableDesc->Pointer = NULL; 53467754Smsmith} 53567754Smsmith 53667754Smsmith 53767754Smsmith/******************************************************************************* 53867754Smsmith * 539167802Sjkim * FUNCTION: AcpiTbTerminate 54067754Smsmith * 541167802Sjkim * PARAMETERS: None 54267754Smsmith * 543167802Sjkim * RETURN: None 54467754Smsmith * 54567754Smsmith * DESCRIPTION: Delete all internal ACPI tables 54667754Smsmith * 54767754Smsmith ******************************************************************************/ 54867754Smsmith 54967754Smsmithvoid 550167802SjkimAcpiTbTerminate ( 551151937Sjkim void) 55267754Smsmith{ 553193267Sjkim UINT32 i; 55467754Smsmith 55567754Smsmith 556167802Sjkim ACPI_FUNCTION_TRACE (TbTerminate); 557167802Sjkim 558167802Sjkim 559167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 560167802Sjkim 561167802Sjkim /* Delete the individual tables */ 562167802Sjkim 563207344Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 564167802Sjkim { 565167802Sjkim AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); 566167802Sjkim } 567167802Sjkim 56867754Smsmith /* 569167802Sjkim * Delete the root table array if allocated locally. Array cannot be 570167802Sjkim * mapped, so we don't need to check for that flag. 57167754Smsmith */ 572167802Sjkim if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 57367754Smsmith { 574167802Sjkim ACPI_FREE (AcpiGbl_RootTableList.Tables); 57567754Smsmith } 576167802Sjkim 577167802Sjkim AcpiGbl_RootTableList.Tables = NULL; 578167802Sjkim AcpiGbl_RootTableList.Flags = 0; 579207344Sjkim AcpiGbl_RootTableList.CurrentTableCount = 0; 580167802Sjkim 581167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 582167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 583241973Sjkim 584241973Sjkim return_VOID; 58567754Smsmith} 58667754Smsmith 58767754Smsmith 58867754Smsmith/******************************************************************************* 58967754Smsmith * 590167802Sjkim * FUNCTION: AcpiTbDeleteNamespaceByOwner 59167754Smsmith * 592167802Sjkim * PARAMETERS: TableIndex - Table index 59367754Smsmith * 594193267Sjkim * RETURN: Status 59567754Smsmith * 596167802Sjkim * DESCRIPTION: Delete all namespace objects created when this table was loaded. 59767754Smsmith * 59867754Smsmith ******************************************************************************/ 59967754Smsmith 600193267SjkimACPI_STATUS 601167802SjkimAcpiTbDeleteNamespaceByOwner ( 602193267Sjkim UINT32 TableIndex) 60367754Smsmith{ 604167802Sjkim ACPI_OWNER_ID OwnerId; 605193267Sjkim ACPI_STATUS Status; 60667754Smsmith 60767754Smsmith 608193267Sjkim ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 609193267Sjkim 610193267Sjkim 611193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 612193267Sjkim if (ACPI_FAILURE (Status)) 61367754Smsmith { 614193267Sjkim return_ACPI_STATUS (Status); 61567754Smsmith } 616193267Sjkim 617207344Sjkim if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 61891116Smsmith { 619193267Sjkim /* The table index does not exist */ 620193267Sjkim 621167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 622193267Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 62391116Smsmith } 62467754Smsmith 625193267Sjkim /* Get the owner ID for this table, used to delete namespace nodes */ 626193267Sjkim 627193267Sjkim OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 628167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 629193267Sjkim 630193267Sjkim /* 631193267Sjkim * Need to acquire the namespace writer lock to prevent interference 632193267Sjkim * with any concurrent namespace walks. The interpreter must be 633193267Sjkim * released during the deletion since the acquisition of the deletion 634193267Sjkim * lock may block, and also since the execution of a namespace walk 635193267Sjkim * must be allowed to use the interpreter. 636193267Sjkim */ 637193267Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 638193267Sjkim Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 639193267Sjkim 640167802Sjkim AcpiNsDeleteNamespaceByOwner (OwnerId); 641193267Sjkim if (ACPI_FAILURE (Status)) 642193267Sjkim { 643193267Sjkim return_ACPI_STATUS (Status); 644193267Sjkim } 645193267Sjkim 646193267Sjkim AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 647193267Sjkim 648193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 649193267Sjkim return_ACPI_STATUS (Status); 650167802Sjkim} 65167754Smsmith 65267754Smsmith 653167802Sjkim/******************************************************************************* 654167802Sjkim * 655167802Sjkim * FUNCTION: AcpiTbAllocateOwnerId 656167802Sjkim * 657167802Sjkim * PARAMETERS: TableIndex - Table index 658167802Sjkim * 659167802Sjkim * RETURN: Status 660167802Sjkim * 661167802Sjkim * DESCRIPTION: Allocates OwnerId in TableDesc 662167802Sjkim * 663167802Sjkim ******************************************************************************/ 66467754Smsmith 665167802SjkimACPI_STATUS 666167802SjkimAcpiTbAllocateOwnerId ( 667193267Sjkim UINT32 TableIndex) 668167802Sjkim{ 669167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 67067754Smsmith 67167754Smsmith 672167802Sjkim ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 67367754Smsmith 67467754Smsmith 675167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 676207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 67767754Smsmith { 678167802Sjkim Status = AcpiUtAllocateOwnerId 679167802Sjkim (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 68067754Smsmith } 68167754Smsmith 682117521Snjl (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 683167802Sjkim return_ACPI_STATUS (Status); 68467754Smsmith} 68567754Smsmith 68667754Smsmith 68767754Smsmith/******************************************************************************* 68867754Smsmith * 689167802Sjkim * FUNCTION: AcpiTbReleaseOwnerId 69067754Smsmith * 691167802Sjkim * PARAMETERS: TableIndex - Table index 69267754Smsmith * 693167802Sjkim * RETURN: Status 69467754Smsmith * 695167802Sjkim * DESCRIPTION: Releases OwnerId in TableDesc 69667754Smsmith * 69767754Smsmith ******************************************************************************/ 69867754Smsmith 699167802SjkimACPI_STATUS 700167802SjkimAcpiTbReleaseOwnerId ( 701193267Sjkim UINT32 TableIndex) 70267754Smsmith{ 703167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 70467754Smsmith 705117521Snjl 706167802Sjkim ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 70767754Smsmith 708117521Snjl 709167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 710207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 71167754Smsmith { 712193267Sjkim AcpiUtReleaseOwnerId ( 713193267Sjkim &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 714167802Sjkim Status = AE_OK; 715167802Sjkim } 71667754Smsmith 717167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 718167802Sjkim return_ACPI_STATUS (Status); 71967754Smsmith} 72067754Smsmith 72167754Smsmith 72267754Smsmith/******************************************************************************* 72367754Smsmith * 724167802Sjkim * FUNCTION: AcpiTbGetOwnerId 72567754Smsmith * 726167802Sjkim * PARAMETERS: TableIndex - Table index 727167802Sjkim * OwnerId - Where the table OwnerId is returned 72867754Smsmith * 729167802Sjkim * RETURN: Status 73067754Smsmith * 731167802Sjkim * DESCRIPTION: returns OwnerId for the ACPI table 73267754Smsmith * 73367754Smsmith ******************************************************************************/ 73467754Smsmith 735167802SjkimACPI_STATUS 736167802SjkimAcpiTbGetOwnerId ( 737193267Sjkim UINT32 TableIndex, 738167802Sjkim ACPI_OWNER_ID *OwnerId) 73967754Smsmith{ 740167802Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 74167754Smsmith 74267754Smsmith 743167802Sjkim ACPI_FUNCTION_TRACE (TbGetOwnerId); 74467754Smsmith 74567754Smsmith 746167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 747207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 74867754Smsmith { 749167802Sjkim *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 750167802Sjkim Status = AE_OK; 75167754Smsmith } 75267754Smsmith 753167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 754167802Sjkim return_ACPI_STATUS (Status); 755167802Sjkim} 75667754Smsmith 75767754Smsmith 758167802Sjkim/******************************************************************************* 759167802Sjkim * 760167802Sjkim * FUNCTION: AcpiTbIsTableLoaded 761167802Sjkim * 762167802Sjkim * PARAMETERS: TableIndex - Table index 763167802Sjkim * 764167802Sjkim * RETURN: Table Loaded Flag 765167802Sjkim * 766167802Sjkim ******************************************************************************/ 767117521Snjl 768167802SjkimBOOLEAN 769167802SjkimAcpiTbIsTableLoaded ( 770193267Sjkim UINT32 TableIndex) 771167802Sjkim{ 772167802Sjkim BOOLEAN IsLoaded = FALSE; 773167802Sjkim 774167802Sjkim 775167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 776207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 77767754Smsmith { 778167802Sjkim IsLoaded = (BOOLEAN) 779193267Sjkim (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 780193267Sjkim ACPI_TABLE_IS_LOADED); 78167754Smsmith } 78267754Smsmith 783167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 784167802Sjkim return (IsLoaded); 785167802Sjkim} 78667754Smsmith 78767754Smsmith 788167802Sjkim/******************************************************************************* 789167802Sjkim * 790167802Sjkim * FUNCTION: AcpiTbSetTableLoadedFlag 791167802Sjkim * 792167802Sjkim * PARAMETERS: TableIndex - Table index 793167802Sjkim * IsLoaded - TRUE if table is loaded, FALSE otherwise 794167802Sjkim * 795167802Sjkim * RETURN: None 796167802Sjkim * 797167802Sjkim * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 798167802Sjkim * 799167802Sjkim ******************************************************************************/ 80067754Smsmith 801167802Sjkimvoid 802167802SjkimAcpiTbSetTableLoadedFlag ( 803193267Sjkim UINT32 TableIndex, 804167802Sjkim BOOLEAN IsLoaded) 805167802Sjkim{ 80667754Smsmith 807167802Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 808207344Sjkim if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 809167802Sjkim { 810167802Sjkim if (IsLoaded) 811167802Sjkim { 812193267Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 813193267Sjkim ACPI_TABLE_IS_LOADED; 814167802Sjkim } 815167802Sjkim else 816167802Sjkim { 817193267Sjkim AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 818193267Sjkim ~ACPI_TABLE_IS_LOADED; 819167802Sjkim } 820167802Sjkim } 82167754Smsmith 822167802Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 82367754Smsmith} 824