utmisc.c revision 73561
1189251Ssam/******************************************************************************* 2189251Ssam * 3189251Ssam * Module Name: cmutils - common utility procedures 4189251Ssam * $Revision: 27 $ 5189251Ssam * 6189251Ssam ******************************************************************************/ 7189251Ssam 8189251Ssam/****************************************************************************** 9189251Ssam * 10189251Ssam * 1. Copyright Notice 11189251Ssam * 12189251Ssam * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 13189251Ssam * All rights reserved. 14189251Ssam * 15189251Ssam * 2. License 16189251Ssam * 17189251Ssam * 2.1. This is your license from Intel Corp. under its intellectual property 18189251Ssam * rights. You may have additional license terms from the party that provided 19189251Ssam * you this software, covering your right to use that party's intellectual 20189251Ssam * property rights. 21189251Ssam * 22189251Ssam * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23189251Ssam * copy of the source code appearing in this file ("Covered Code") an 24189251Ssam * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25189251Ssam * base code distributed originally by Intel ("Original Intel Code") to copy, 26189251Ssam * make derivatives, distribute, use and display any portion of the Covered 27189251Ssam * Code in any form, with the right to sublicense such rights; and 28189251Ssam * 29189251Ssam * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30189251Ssam * license (with the right to sublicense), under only those claims of Intel 31189251Ssam * patents that are infringed by the Original Intel Code, to make, use, sell, 32189251Ssam * offer to sell, and import the Covered Code and derivative works thereof 33189251Ssam * solely to the minimum extent necessary to exercise the above copyright 34189251Ssam * license, and in no event shall the patent license extend to any additions 35189251Ssam * to or modifications of the Original Intel Code. No other license or right 36189251Ssam * is granted directly or by implication, estoppel or otherwise; 37189251Ssam * 38189251Ssam * The above copyright and patent license is granted only if the following 39189251Ssam * conditions are met: 40189251Ssam * 41189251Ssam * 3. Conditions 42189251Ssam * 43189251Ssam * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44189251Ssam * Redistribution of source code of any substantial portion of the Covered 45189251Ssam * Code or modification with rights to further distribute source must include 46189251Ssam * the above Copyright Notice, the above License, this list of Conditions, 47189251Ssam * and the following Disclaimer and Export Compliance provision. In addition, 48189251Ssam * Licensee must cause all Covered Code to which Licensee contributes to 49189251Ssam * contain a file documenting the changes Licensee made to create that Covered 50189251Ssam * Code and the date of any change. Licensee must include in that file the 51189251Ssam * documentation of any changes made by any predecessor Licensee. Licensee 52189251Ssam * must include a prominent statement that the modification is derived, 53189251Ssam * directly or indirectly, from Original Intel Code. 54189251Ssam * 55189251Ssam * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56189251Ssam * Redistribution of source code of any substantial portion of the Covered 57189251Ssam * Code or modification without rights to further distribute source must 58189251Ssam * include the following Disclaimer and Export Compliance provision in the 59189251Ssam * documentation and/or other materials provided with distribution. In 60189251Ssam * addition, Licensee may not authorize further sublicense of source of any 61189251Ssam * portion of the Covered Code, and must include terms to the effect that the 62189251Ssam * license from Licensee to its licensee is limited to the intellectual 63189251Ssam * property embodied in the software Licensee provides to its licensee, and 64189251Ssam * not to intellectual property embodied in modifications its licensee may 65189251Ssam * make. 66189251Ssam * 67189251Ssam * 3.3. Redistribution of Executable. Redistribution in executable form of any 68189251Ssam * substantial portion of the Covered Code or modification must reproduce the 69189251Ssam * above Copyright Notice, and the following Disclaimer and Export Compliance 70189251Ssam * provision in the documentation and/or other materials provided with the 71189251Ssam * distribution. 72189251Ssam * 73189251Ssam * 3.4. Intel retains all right, title, and interest in and to the Original 74189251Ssam * Intel Code. 75189251Ssam * 76189251Ssam * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77189251Ssam * Intel shall be used in advertising or otherwise to promote the sale, use or 78189251Ssam * other dealings in products derived from or relating to the Covered Code 79189251Ssam * without prior written authorization from Intel. 80189251Ssam * 81189251Ssam * 4. Disclaimer and Export Compliance 82189251Ssam * 83189251Ssam * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84189251Ssam * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85189251Ssam * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86189251Ssam * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87189251Ssam * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88189251Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89189251Ssam * PARTICULAR PURPOSE. 90189251Ssam * 91189251Ssam * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92189251Ssam * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93189251Ssam * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94189251Ssam * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95189251Ssam * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96189251Ssam * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97189251Ssam * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98189251Ssam * LIMITED REMEDY. 99189251Ssam * 100189251Ssam * 4.3. Licensee shall not export, either directly or indirectly, any of this 101189251Ssam * software or system incorporating such software without first obtaining any 102189251Ssam * required license or other approval from the U. S. Department of Commerce or 103189251Ssam * any other agency or department of the United States Government. In the 104189251Ssam * event Licensee exports any such software from the United States or 105189251Ssam * re-exports any such software from a foreign destination, Licensee shall 106189251Ssam * ensure that the distribution and export/re-export of the software is in 107189251Ssam * compliance with all laws, regulations, orders, or other restrictions of the 108189251Ssam * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109189251Ssam * any of its subsidiaries will export/re-export any technical data, process, 110189251Ssam * software, or service, directly or indirectly, to any country for which the 111189251Ssam * United States government or any agency thereof requires an export license, 112189251Ssam * other governmental approval, or letter of assurance, without first obtaining 113189251Ssam * such license, approval or letter. 114189251Ssam * 115189251Ssam *****************************************************************************/ 116189251Ssam 117189251Ssam 118189251Ssam#define __CMUTILS_C__ 119189251Ssam 120189251Ssam#include "acpi.h" 121189251Ssam#include "acevents.h" 122189251Ssam#include "achware.h" 123189251Ssam#include "acnamesp.h" 124189251Ssam#include "acinterp.h" 125189251Ssam#include "amlcode.h" 126189251Ssam#include "acdebug.h" 127189251Ssam 128189251Ssam 129189251Ssam#define _COMPONENT MISCELLANEOUS 130189251Ssam MODULE_NAME ("cmutils") 131189251Ssam 132189251Ssam 133189251Ssam/******************************************************************************* 134189251Ssam * 135189251Ssam * FUNCTION: AcpiCmValidAcpiName 136189251Ssam * 137189251Ssam * PARAMETERS: Character - The character to be examined 138189251Ssam * 139189251Ssam * RETURN: 1 if Character may appear in a name, else 0 140189251Ssam * 141189251Ssam * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 142189251Ssam * 1) Upper case alpha 143189251Ssam * 2) numeric 144189251Ssam * 3) underscore 145189251Ssam * 146189251Ssam ******************************************************************************/ 147189251Ssam 148189251SsamBOOLEAN 149189251SsamAcpiCmValidAcpiName ( 150189251Ssam UINT32 Name) 151189251Ssam{ 152189251Ssam NATIVE_CHAR *NamePtr = (NATIVE_CHAR *) &Name; 153189251Ssam UINT32 i; 154189251Ssam 155189251Ssam 156189251Ssam for (i = 0; i < ACPI_NAME_SIZE; i++) 157189251Ssam { 158189251Ssam if (!((NamePtr[i] == '_') || 159189251Ssam (NamePtr[i] >= 'A' && NamePtr[i] <= 'Z') || 160189251Ssam (NamePtr[i] >= '0' && NamePtr[i] <= '9'))) 161189251Ssam { 162189251Ssam return (FALSE); 163189251Ssam } 164189251Ssam } 165189251Ssam 166189251Ssam 167189251Ssam return (TRUE); 168189251Ssam} 169189251Ssam 170189251Ssam 171189251Ssam/******************************************************************************* 172189251Ssam * 173189251Ssam * FUNCTION: AcpiCmValidAcpiCharacter 174189251Ssam * 175189251Ssam * PARAMETERS: Character - The character to be examined 176189251Ssam * 177189251Ssam * RETURN: 1 if Character may appear in a name, else 0 178189251Ssam * 179189251Ssam * DESCRIPTION: Check for a printable character 180189251Ssam * 181189251Ssam ******************************************************************************/ 182189251Ssam 183189251SsamBOOLEAN 184189251SsamAcpiCmValidAcpiCharacter ( 185189251Ssam NATIVE_CHAR Character) 186189251Ssam{ 187189251Ssam 188189251Ssam return ((BOOLEAN) ((Character == '_') || 189189251Ssam (Character >= 'A' && Character <= 'Z') || 190189251Ssam (Character >= '0' && Character <= '9'))); 191189251Ssam} 192189251Ssam 193189251Ssam 194189251Ssam/******************************************************************************* 195189251Ssam * 196189251Ssam * FUNCTION: AcpiCmMutexInitialize 197189251Ssam * 198189251Ssam * PARAMETERS: None. 199189251Ssam * 200189251Ssam * RETURN: Status 201189251Ssam * 202189251Ssam * DESCRIPTION: Create the system mutex objects. 203189251Ssam * 204189251Ssam ******************************************************************************/ 205189251Ssam 206189251SsamACPI_STATUS 207189251SsamAcpiCmMutexInitialize ( 208189251Ssam void) 209189251Ssam{ 210189251Ssam UINT32 i; 211189251Ssam ACPI_STATUS Status; 212189251Ssam 213189251Ssam 214189251Ssam FUNCTION_TRACE ("CmMutexInitialize"); 215189251Ssam 216189251Ssam 217189251Ssam /* 218189251Ssam * Create each of the predefined mutex objects 219189251Ssam */ 220189251Ssam for (i = 0; i < NUM_MTX; i++) 221189251Ssam { 222189251Ssam Status = AcpiCmCreateMutex (i); 223189251Ssam if (ACPI_FAILURE (Status)) 224189251Ssam { 225189251Ssam return_ACPI_STATUS (Status); 226189251Ssam } 227189251Ssam } 228189251Ssam 229189251Ssam return_ACPI_STATUS (AE_OK); 230189251Ssam} 231189251Ssam 232189251Ssam 233189251Ssam/******************************************************************************* 234189251Ssam * 235189251Ssam * FUNCTION: AcpiCmMutexTerminate 236189251Ssam * 237189251Ssam * PARAMETERS: None. 238189251Ssam * 239189251Ssam * RETURN: None. 240189251Ssam * 241189251Ssam * DESCRIPTION: Delete all of the system mutex objects. 242189251Ssam * 243189251Ssam ******************************************************************************/ 244189251Ssam 245189251Ssamvoid 246189251SsamAcpiCmMutexTerminate ( 247189251Ssam void) 248189251Ssam{ 249189251Ssam UINT32 i; 250189251Ssam 251189251Ssam 252189251Ssam FUNCTION_TRACE ("CmMutexTerminate"); 253189251Ssam 254189251Ssam 255189251Ssam /* 256189251Ssam * Delete each predefined mutex object 257189251Ssam */ 258189251Ssam for (i = 0; i < NUM_MTX; i++) 259189251Ssam { 260189251Ssam AcpiCmDeleteMutex (i); 261189251Ssam } 262189251Ssam 263189251Ssam return_VOID; 264189251Ssam} 265189251Ssam 266189251Ssam 267189251Ssam/******************************************************************************* 268189251Ssam * 269189251Ssam * FUNCTION: AcpiCmCreateMutex 270189251Ssam * 271189251Ssam * PARAMETERS: MutexID - ID of the mutex to be created 272189251Ssam * 273189251Ssam * RETURN: Status 274189251Ssam * 275189251Ssam * DESCRIPTION: Create a mutex object. 276189251Ssam * 277189251Ssam ******************************************************************************/ 278189251Ssam 279189251SsamACPI_STATUS 280189251SsamAcpiCmCreateMutex ( 281189251Ssam ACPI_MUTEX_HANDLE MutexId) 282189251Ssam{ 283189251Ssam ACPI_STATUS Status = AE_OK; 284189251Ssam 285189251Ssam 286189251Ssam FUNCTION_TRACE_U32 ("CmCreateMutex", MutexId); 287189251Ssam 288189251Ssam 289189251Ssam if (MutexId > MAX_MTX) 290189251Ssam { 291189251Ssam return_ACPI_STATUS (AE_BAD_PARAMETER); 292189251Ssam } 293189251Ssam 294189251Ssam 295189251Ssam if (!AcpiGbl_AcpiMutexInfo[MutexId].Mutex) 296189251Ssam { 297189251Ssam Status = AcpiOsCreateSemaphore (1, 1, 298189251Ssam &AcpiGbl_AcpiMutexInfo[MutexId].Mutex); 299189251Ssam AcpiGbl_AcpiMutexInfo[MutexId].Locked = FALSE; 300189251Ssam AcpiGbl_AcpiMutexInfo[MutexId].UseCount = 0; 301189251Ssam } 302189251Ssam 303189251Ssam return_ACPI_STATUS (Status); 304189251Ssam} 305189251Ssam 306189251Ssam 307189251Ssam/******************************************************************************* 308189251Ssam * 309189251Ssam * FUNCTION: AcpiCmDeleteMutex 310189251Ssam * 311189251Ssam * PARAMETERS: MutexID - ID of the mutex to be deleted 312189251Ssam * 313189251Ssam * RETURN: Status 314189251Ssam * 315189251Ssam * DESCRIPTION: Delete a mutex object. 316189251Ssam * 317189251Ssam ******************************************************************************/ 318189251Ssam 319189251SsamACPI_STATUS 320189251SsamAcpiCmDeleteMutex ( 321189251Ssam ACPI_MUTEX_HANDLE MutexId) 322189251Ssam{ 323189251Ssam ACPI_STATUS Status; 324189251Ssam 325189251Ssam 326189251Ssam FUNCTION_TRACE_U32 ("CmDeleteMutex", MutexId); 327189251Ssam 328189251Ssam 329189251Ssam if (MutexId > MAX_MTX) 330189251Ssam { 331189251Ssam return_ACPI_STATUS (AE_BAD_PARAMETER); 332189251Ssam } 333189251Ssam 334189251Ssam 335189251Ssam Status = AcpiOsDeleteSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex); 336189251Ssam 337189251Ssam AcpiGbl_AcpiMutexInfo[MutexId].Mutex = NULL; 338189251Ssam AcpiGbl_AcpiMutexInfo[MutexId].Locked = FALSE; 339189251Ssam 340189251Ssam return_ACPI_STATUS (Status); 341189251Ssam} 342189251Ssam 343189251Ssam 344189251Ssam/******************************************************************************* 345189251Ssam * 346189251Ssam * FUNCTION: AcpiCmAcquireMutex 347189251Ssam * 348189251Ssam * PARAMETERS: MutexID - ID of the mutex to be acquired 349189251Ssam * 350189251Ssam * RETURN: Status 351189251Ssam * 352189251Ssam * DESCRIPTION: Acquire a mutex object. 353189251Ssam * 354189251Ssam ******************************************************************************/ 355189251Ssam 356189251SsamACPI_STATUS 357189251SsamAcpiCmAcquireMutex ( 358189251Ssam ACPI_MUTEX_HANDLE MutexId) 359189251Ssam{ 360189251Ssam ACPI_STATUS Status; 361189251Ssam 362189251Ssam 363189251Ssam DEBUG_PRINT (TRACE_MUTEX, 364189251Ssam ("Acquiring Mutex [%s]\n", AcpiCmGetMutexName (MutexId))); 365189251Ssam 366189251Ssam if (MutexId > MAX_MTX) 367189251Ssam { 368189251Ssam return (AE_BAD_PARAMETER); 369189251Ssam } 370189251Ssam 371189251Ssam 372189251Ssam Status = AcpiOsWaitSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 373189251Ssam 1, WAIT_FOREVER); 374189251Ssam 375189251Ssam DEBUG_PRINT (TRACE_MUTEX, ("Acquired Mutex [%s] Status %s\n", 376189251Ssam AcpiCmGetMutexName (MutexId), AcpiCmFormatException (Status))); 377189251Ssam 378189251Ssam if (ACPI_SUCCESS (Status)) 379189251Ssam { 380189251Ssam AcpiGbl_AcpiMutexInfo[MutexId].Locked = TRUE; 381189251Ssam AcpiGbl_AcpiMutexInfo[MutexId].UseCount++; 382189251Ssam } 383189251Ssam 384189251Ssam return (Status); 385189251Ssam} 386189251Ssam 387189251Ssam 388189251Ssam/******************************************************************************* 389189251Ssam * 390189251Ssam * FUNCTION: AcpiCmReleaseMutex 391189251Ssam * 392189251Ssam * PARAMETERS: MutexID - ID of the mutex to be released 393189251Ssam * 394189251Ssam * RETURN: Status 395189251Ssam * 396189251Ssam * DESCRIPTION: Release a mutex object. 397189251Ssam * 398189251Ssam ******************************************************************************/ 399189251Ssam 400189251SsamACPI_STATUS 401189251SsamAcpiCmReleaseMutex ( 402189251Ssam ACPI_MUTEX_HANDLE MutexId) 403189251Ssam{ 404189251Ssam ACPI_STATUS Status; 405189251Ssam 406189251Ssam 407189251Ssam DEBUG_PRINT (TRACE_MUTEX, 408189251Ssam ("Releasing Mutex [%s]\n", AcpiCmGetMutexName (MutexId))); 409189251Ssam 410189251Ssam if (MutexId > MAX_MTX) 411189251Ssam { 412189251Ssam return (AE_BAD_PARAMETER); 413189251Ssam } 414189251Ssam 415189251Ssam 416189251Ssam AcpiGbl_AcpiMutexInfo[MutexId].Locked = FALSE; /* Mark before unlocking */ 417189251Ssam 418189251Ssam Status = AcpiOsSignalSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1); 419189251Ssam 420189251Ssam if (ACPI_FAILURE (Status)) 421189251Ssam { 422189251Ssam DEBUG_PRINT (ACPI_ERROR, ("Error Releasing Mutex [%s], %s\n", 423189251Ssam AcpiCmGetMutexName (MutexId), AcpiCmFormatException (Status))); 424189251Ssam } 425189251Ssam else 426189251Ssam { 427189251Ssam DEBUG_PRINT (TRACE_MUTEX, ("Released Mutex [%s], %s\n", 428189251Ssam AcpiCmGetMutexName (MutexId), AcpiCmFormatException (Status))); 429189251Ssam } 430189251Ssam 431189251Ssam return (Status); 432189251Ssam} 433189251Ssam 434189251Ssam 435189251Ssam/******************************************************************************* 436189251Ssam * 437189251Ssam * FUNCTION: AcpiCmCreateUpdateStateAndPush 438189251Ssam * 439189251Ssam * PARAMETERS: *Object - Object to be added to the new state 440189251Ssam * Action - Increment/Decrement 441189251Ssam * StateList - List the state will be added to 442189251Ssam * 443189251Ssam * RETURN: None 444189251Ssam * 445189251Ssam * DESCRIPTION: Create a new state and push it 446189251Ssam * 447189251Ssam ******************************************************************************/ 448189251Ssam 449189251SsamACPI_STATUS 450189251SsamAcpiCmCreateUpdateStateAndPush ( 451189251Ssam ACPI_OPERAND_OBJECT *Object, 452189251Ssam UINT16 Action, 453189251Ssam ACPI_GENERIC_STATE **StateList) 454189251Ssam{ 455189251Ssam ACPI_GENERIC_STATE *State; 456189251Ssam 457189251Ssam 458189251Ssam /* Ignore null objects; these are expected */ 459189251Ssam 460189251Ssam if (!Object) 461189251Ssam { 462189251Ssam return (AE_OK); 463189251Ssam } 464189251Ssam 465189251Ssam State = AcpiCmCreateUpdateState (Object, Action); 466189251Ssam if (!State) 467189251Ssam { 468189251Ssam return (AE_NO_MEMORY); 469189251Ssam } 470189251Ssam 471189251Ssam 472189251Ssam AcpiCmPushGenericState (StateList, State); 473189251Ssam return (AE_OK); 474189251Ssam} 475189251Ssam 476189251Ssam 477189251Ssam/******************************************************************************* 478189251Ssam * 479189251Ssam * FUNCTION: AcpiCmCreatePkgStateAndPush 480189251Ssam * 481189251Ssam * PARAMETERS: *Object - Object to be added to the new state 482189251Ssam * Action - Increment/Decrement 483189251Ssam * StateList - List the state will be added to 484189251Ssam * 485189251Ssam * RETURN: None 486189251Ssam * 487189251Ssam * DESCRIPTION: Create a new state and push it 488189251Ssam * 489189251Ssam ******************************************************************************/ 490189251Ssam 491189251SsamACPI_STATUS 492189251SsamAcpiCmCreatePkgStateAndPush ( 493189251Ssam void *InternalObject, 494189251Ssam void *ExternalObject, 495189251Ssam UINT16 Index, 496189251Ssam ACPI_GENERIC_STATE **StateList) 497189251Ssam{ 498189251Ssam ACPI_GENERIC_STATE *State; 499189251Ssam 500189251Ssam 501189251Ssam 502189251Ssam State = AcpiCmCreatePkgState (InternalObject, ExternalObject, Index); 503189251Ssam if (!State) 504189251Ssam { 505189251Ssam return (AE_NO_MEMORY); 506189251Ssam } 507189251Ssam 508189251Ssam 509189251Ssam AcpiCmPushGenericState (StateList, State); 510189251Ssam return (AE_OK); 511189251Ssam} 512189251Ssam 513189251Ssam 514189251Ssam 515189251Ssam/******************************************************************************* 516189251Ssam * 517189251Ssam * FUNCTION: AcpiCmPushGenericState 518189251Ssam * 519189251Ssam * PARAMETERS: ListHead - Head of the state stack 520189251Ssam * State - State object to push 521189251Ssam * 522189251Ssam * RETURN: Status 523189251Ssam * 524189251Ssam * DESCRIPTION: Push a state object onto a state stack 525189251Ssam * 526189251Ssam ******************************************************************************/ 527189251Ssam 528189251Ssamvoid 529189251SsamAcpiCmPushGenericState ( 530189251Ssam ACPI_GENERIC_STATE **ListHead, 531189251Ssam ACPI_GENERIC_STATE *State) 532189251Ssam{ 533 FUNCTION_TRACE ("CmPushGenericState"); 534 535 /* Push the state object onto the front of the list (stack) */ 536 537 State->Common.Next = *ListHead; 538 *ListHead = State; 539 540 return_VOID; 541} 542 543 544/******************************************************************************* 545 * 546 * FUNCTION: AcpiCmPopGenericState 547 * 548 * PARAMETERS: ListHead - Head of the state stack 549 * 550 * RETURN: Status 551 * 552 * DESCRIPTION: Pop a state object from a state stack 553 * 554 ******************************************************************************/ 555 556ACPI_GENERIC_STATE * 557AcpiCmPopGenericState ( 558 ACPI_GENERIC_STATE **ListHead) 559{ 560 ACPI_GENERIC_STATE *State; 561 562 563 FUNCTION_TRACE ("DsPopGenericState"); 564 565 566 /* Remove the state object at the head of the list (stack) */ 567 568 State = *ListHead; 569 if (State) 570 { 571 /* Update the list head */ 572 573 *ListHead = State->Common.Next; 574 } 575 576 return_PTR (State); 577} 578 579 580/******************************************************************************* 581 * 582 * FUNCTION: AcpiCmCreateGenericState 583 * 584 * PARAMETERS: None 585 * 586 * RETURN: Status 587 * 588 * DESCRIPTION: Create a generic state object. Attempt to obtain one from 589 * the global state cache; If none available, create a new one. 590 * 591 ******************************************************************************/ 592 593ACPI_GENERIC_STATE * 594AcpiCmCreateGenericState (void) 595{ 596 ACPI_GENERIC_STATE *State; 597 598 599 AcpiCmAcquireMutex (ACPI_MTX_CACHES); 600 601 AcpiGbl_StateCacheRequests++; 602 603 /* Check the cache first */ 604 605 if (AcpiGbl_GenericStateCache) 606 { 607 /* There is an object available, use it */ 608 609 State = AcpiGbl_GenericStateCache; 610 AcpiGbl_GenericStateCache = State->Common.Next; 611 State->Common.Next = NULL; 612 613 AcpiGbl_StateCacheHits++; 614 AcpiGbl_GenericStateCacheDepth--; 615 616 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 617 618 DEBUG_PRINT (TRACE_EXEC, ("CreateGenState: State %p from cache\n", State)); 619 } 620 621 else 622 { 623 /* The cache is empty, create a new object */ 624 625 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 626 627 State = AcpiCmCallocate (sizeof (ACPI_GENERIC_STATE)); 628 } 629 630 /* Initialize */ 631 632 if (State) 633 { 634 /* Always zero out the object before init */ 635 636 MEMSET (State, 0, sizeof (ACPI_GENERIC_STATE)); 637 638 State->Common.DataType = ACPI_DESC_TYPE_STATE; 639 } 640 641 return (State); 642} 643 644 645/******************************************************************************* 646 * 647 * FUNCTION: AcpiCmCreateUpdateState 648 * 649 * PARAMETERS: Object - Initial Object to be installed in the 650 * state 651 * Action - Update action to be performed 652 * 653 * RETURN: Status 654 * 655 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 656 * to update reference counts and delete complex objects such 657 * as packages. 658 * 659 ******************************************************************************/ 660 661ACPI_GENERIC_STATE * 662AcpiCmCreateUpdateState ( 663 ACPI_OPERAND_OBJECT *Object, 664 UINT16 Action) 665{ 666 ACPI_GENERIC_STATE *State; 667 668 669 FUNCTION_TRACE_PTR ("CmCreateUpdateState", Object); 670 671 672 /* Create the generic state object */ 673 674 State = AcpiCmCreateGenericState (); 675 if (!State) 676 { 677 return (NULL); 678 } 679 680 /* Init fields specific to the update struct */ 681 682 State->Update.Object = Object; 683 State->Update.Value = Action; 684 685 return_PTR (State); 686} 687 688 689/******************************************************************************* 690 * 691 * FUNCTION: AcpiCmCreatePkgState 692 * 693 * PARAMETERS: Object - Initial Object to be installed in the 694 * state 695 * Action - Update action to be performed 696 * 697 * RETURN: Status 698 * 699 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 700 * to update reference counts and delete complex objects such 701 * as packages. 702 * 703 ******************************************************************************/ 704 705ACPI_GENERIC_STATE * 706AcpiCmCreatePkgState ( 707 void *InternalObject, 708 void *ExternalObject, 709 UINT16 Index) 710{ 711 ACPI_GENERIC_STATE *State; 712 713 714 FUNCTION_TRACE_PTR ("CmCreatePkgState", InternalObject); 715 716 717 /* Create the generic state object */ 718 719 State = AcpiCmCreateGenericState (); 720 if (!State) 721 { 722 return (NULL); 723 } 724 725 /* Init fields specific to the update struct */ 726 727 State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject; 728 State->Pkg.DestObject = ExternalObject; 729 State->Pkg.Index = Index; 730 State->Pkg.NumPackages = 1; 731 732 return_PTR (State); 733} 734 735 736 737/******************************************************************************* 738 * 739 * FUNCTION: AcpiCmCreateControlState 740 * 741 * PARAMETERS: None 742 * 743 * RETURN: Status 744 * 745 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 746 * to support nested IF/WHILE constructs in the AML. 747 * 748 ******************************************************************************/ 749 750ACPI_GENERIC_STATE * 751AcpiCmCreateControlState ( 752 void) 753{ 754 ACPI_GENERIC_STATE *State; 755 756 757 FUNCTION_TRACE ("CmCreateControlState"); 758 759 /* Create the generic state object */ 760 761 State = AcpiCmCreateGenericState (); 762 if (!State) 763 { 764 return (NULL); 765 } 766 767 768 /* Init fields specific to the control struct */ 769 770 State->Common.State = CONTROL_CONDITIONAL_EXECUTING; 771 772 return_PTR (State); 773} 774 775 776/******************************************************************************* 777 * 778 * FUNCTION: AcpiCmDeleteGenericState 779 * 780 * PARAMETERS: State - The state object to be deleted 781 * 782 * RETURN: Status 783 * 784 * DESCRIPTION: Put a state object back into the global state cache. The object 785 * is not actually freed at this time. 786 * 787 ******************************************************************************/ 788 789void 790AcpiCmDeleteGenericState ( 791 ACPI_GENERIC_STATE *State) 792{ 793 FUNCTION_TRACE ("CmDeleteGenericState"); 794 795 796 /* If cache is full, just free this state object */ 797 798 if (AcpiGbl_GenericStateCacheDepth >= MAX_STATE_CACHE_DEPTH) 799 { 800 AcpiCmFree (State); 801 } 802 803 /* Otherwise put this object back into the cache */ 804 805 else 806 { 807 AcpiCmAcquireMutex (ACPI_MTX_CACHES); 808 809 /* Clear the state */ 810 811 MEMSET (State, 0, sizeof (ACPI_GENERIC_STATE)); 812 State->Common.DataType = ACPI_DESC_TYPE_STATE; 813 814 /* Put the object at the head of the global cache list */ 815 816 State->Common.Next = AcpiGbl_GenericStateCache; 817 AcpiGbl_GenericStateCache = State; 818 AcpiGbl_GenericStateCacheDepth++; 819 820 821 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 822 } 823 return_VOID; 824} 825 826 827/******************************************************************************* 828 * 829 * FUNCTION: AcpiCmDeleteGenericStateCache 830 * 831 * PARAMETERS: None 832 * 833 * RETURN: Status 834 * 835 * DESCRIPTION: Purge the global state object cache. Used during subsystem 836 * termination. 837 * 838 ******************************************************************************/ 839 840void 841AcpiCmDeleteGenericStateCache ( 842 void) 843{ 844 ACPI_GENERIC_STATE *Next; 845 846 847 FUNCTION_TRACE ("CmDeleteGenericStateCache"); 848 849 850 /* Traverse the global cache list */ 851 852 while (AcpiGbl_GenericStateCache) 853 { 854 /* Delete one cached state object */ 855 856 Next = AcpiGbl_GenericStateCache->Common.Next; 857 AcpiCmFree (AcpiGbl_GenericStateCache); 858 AcpiGbl_GenericStateCache = Next; 859 AcpiGbl_GenericStateCacheDepth--; 860 } 861 862 return_VOID; 863} 864 865 866/******************************************************************************* 867 * 868 * FUNCTION: AcpiCmResolvePackageReferences 869 * 870 * PARAMETERS: ObjDesc - The Package object on which to resolve refs 871 * 872 * RETURN: Status 873 * 874 * DESCRIPTION: Walk through a package and turn internal references into values 875 * 876 ******************************************************************************/ 877 878ACPI_STATUS 879AcpiCmResolvePackageReferences ( 880 ACPI_OPERAND_OBJECT *ObjDesc) 881{ 882 UINT32 Count; 883 ACPI_OPERAND_OBJECT *SubObject; 884 885 886 FUNCTION_TRACE ("AcpiCmResolvePackageReferences"); 887 888 889 if (ObjDesc->Common.Type != ACPI_TYPE_PACKAGE) 890 { 891 /* The object must be a package */ 892 893 REPORT_ERROR (("Must resolve Package Refs on a Package\n")); 894 return_ACPI_STATUS(AE_ERROR); 895 } 896 897 /* 898 * TBD: what about nested packages? */ 899 900 for (Count = 0; Count < ObjDesc->Package.Count; Count++) 901 { 902 SubObject = ObjDesc->Package.Elements[Count]; 903 904 if (SubObject->Common.Type == INTERNAL_TYPE_REFERENCE) 905 { 906 if (SubObject->Reference.OpCode == AML_ZERO_OP) 907 { 908 SubObject->Common.Type = ACPI_TYPE_INTEGER; 909 SubObject->Integer.Value = 0; 910 } 911 else if (SubObject->Reference.OpCode == AML_ONE_OP) 912 { 913 SubObject->Common.Type = ACPI_TYPE_INTEGER; 914 SubObject->Integer.Value = 1; 915 } 916 else if (SubObject->Reference.OpCode == AML_ONES_OP) 917 { 918 SubObject->Common.Type = ACPI_TYPE_INTEGER; 919 SubObject->Integer.Value = ACPI_INTEGER_MAX; 920 } 921 } 922 } 923 924 return_ACPI_STATUS(AE_OK); 925} 926 927#ifdef ACPI_DEBUG 928 929/****************************************************************************** 930 * 931 * FUNCTION: AcpiCmDisplayInitPathname 932 * 933 * PARAMETERS: ObjHandle - Handle whose pathname will be displayed 934 * Path - Additional path string to be appended 935 * 936 * RETURN: ACPI_STATUS 937 * 938 * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY 939 * 940 *****************************************************************************/ 941 942void 943AcpiCmDisplayInitPathname ( 944 ACPI_HANDLE ObjHandle, 945 char *Path) 946{ 947 ACPI_STATUS Status; 948 UINT32 Length = 128; 949 char Buffer[128]; 950 951 952 Status = AcpiNsHandleToPathname (ObjHandle, &Length, Buffer); 953 if (ACPI_SUCCESS (Status)) 954 { 955 if (Path) 956 { 957 DEBUG_PRINT (TRACE_INIT, ("%s.%s\n", Buffer, Path)) 958 } 959 else 960 { 961 DEBUG_PRINT (TRACE_INIT, ("%s\n", Buffer)) 962 } 963 } 964} 965#endif 966 967/******************************************************************************* 968 * 969 * FUNCTION: AcpiCmWalkPackageTree 970 * 971 * PARAMETERS: ObjDesc - The Package object on which to resolve refs 972 * 973 * RETURN: Status 974 * 975 * DESCRIPTION: Walk through a package 976 * 977 ******************************************************************************/ 978 979ACPI_STATUS 980AcpiCmWalkPackageTree ( 981 ACPI_OPERAND_OBJECT *SourceObject, 982 void *TargetObject, 983 ACPI_PKG_CALLBACK WalkCallback, 984 void *Context) 985{ 986 ACPI_STATUS Status = AE_OK; 987 ACPI_GENERIC_STATE *StateList = NULL; 988 ACPI_GENERIC_STATE *State; 989 UINT32 ThisIndex; 990 ACPI_OPERAND_OBJECT *ThisSourceObj; 991 992 993 FUNCTION_TRACE ("AcpiCmWalkPackageTree"); 994 995 996 State = AcpiCmCreatePkgState (SourceObject, TargetObject, 0); 997 if (!State) 998 { 999 return_ACPI_STATUS (AE_NO_MEMORY); 1000 } 1001 1002 while (State) 1003 { 1004 ThisIndex = State->Pkg.Index; 1005 ThisSourceObj = (ACPI_OPERAND_OBJECT *) 1006 State->Pkg.SourceObject->Package.Elements[ThisIndex]; 1007 1008 /* 1009 * Check for 1010 * 1) An uninitialized package element. It is completely 1011 * legal to declare a package and leave it uninitialized 1012 * 2) Not an internal object - can be a namespace node instead 1013 * 3) Any type other than a package. Packages are handled in else case below. 1014 */ 1015 if ((!ThisSourceObj) || 1016 (!VALID_DESCRIPTOR_TYPE ( 1017 ThisSourceObj, ACPI_DESC_TYPE_INTERNAL)) || 1018 (!IS_THIS_OBJECT_TYPE ( 1019 ThisSourceObj, ACPI_TYPE_PACKAGE))) 1020 { 1021 1022 Status = WalkCallback (0, ThisSourceObj, State, Context); 1023 if (ACPI_FAILURE (Status)) 1024 { 1025 /* TBD: must delete package created up to this point */ 1026 1027 return_ACPI_STATUS (Status); 1028 } 1029 1030 State->Pkg.Index++; 1031 while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count) 1032 { 1033 /* 1034 * We've handled all of the objects at this level, This means 1035 * that we have just completed a package. That package may 1036 * have contained one or more packages itself. 1037 * 1038 * Delete this state and pop the previous state (package). 1039 */ 1040 AcpiCmDeleteGenericState (State); 1041 State = AcpiCmPopGenericState (&StateList); 1042 1043 1044 /* Finished when there are no more states */ 1045 1046 if (!State) 1047 { 1048 /* 1049 * We have handled all of the objects in the top level 1050 * package just add the length of the package objects 1051 * and exit 1052 */ 1053 return_ACPI_STATUS (AE_OK); 1054 } 1055 1056 /* 1057 * Go back up a level and move the index past the just 1058 * completed package object. 1059 */ 1060 State->Pkg.Index++; 1061 } 1062 } 1063 1064 else 1065 { 1066 /* This is a sub-object of type package */ 1067 1068 Status = WalkCallback (1, ThisSourceObj, State, Context); 1069 if (ACPI_FAILURE (Status)) 1070 { 1071 /* TBD: must delete package created up to this point */ 1072 1073 return_ACPI_STATUS (Status); 1074 } 1075 1076 1077 /* 1078 * The callback above returned a new target package object. 1079 */ 1080 1081 /* 1082 * Push the current state and create a new one 1083 */ 1084 AcpiCmPushGenericState (&StateList, State); 1085 State = AcpiCmCreatePkgState (ThisSourceObj, State->Pkg.ThisTargetObj, 0); 1086 if (!State) 1087 { 1088 /* TBD: must delete package created up to this point */ 1089 1090 return_ACPI_STATUS (AE_NO_MEMORY); 1091 } 1092 } 1093 } 1094 1095 /* We should never get here */ 1096 1097 return (AE_AML_INTERNAL); 1098 1099} 1100 1101 1102 1103/******************************************************************************* 1104 * 1105 * FUNCTION: _ReportError 1106 * 1107 * PARAMETERS: ModuleName - Caller's module name (for error output) 1108 * LineNumber - Caller's line number (for error output) 1109 * ComponentId - Caller's component ID (for error output) 1110 * Message - Error message to use on failure 1111 * 1112 * RETURN: None 1113 * 1114 * DESCRIPTION: Print error message 1115 * 1116 ******************************************************************************/ 1117 1118void 1119_ReportError ( 1120 NATIVE_CHAR *ModuleName, 1121 UINT32 LineNumber, 1122 UINT32 ComponentId) 1123{ 1124 1125 1126 AcpiOsPrintf ("%8s-%04d: *** Error: ", ModuleName, LineNumber); 1127} 1128 1129 1130/******************************************************************************* 1131 * 1132 * FUNCTION: _ReportWarning 1133 * 1134 * PARAMETERS: ModuleName - Caller's module name (for error output) 1135 * LineNumber - Caller's line number (for error output) 1136 * ComponentId - Caller's component ID (for error output) 1137 * Message - Error message to use on failure 1138 * 1139 * RETURN: None 1140 * 1141 * DESCRIPTION: Print warning message 1142 * 1143 ******************************************************************************/ 1144 1145void 1146_ReportWarning ( 1147 NATIVE_CHAR *ModuleName, 1148 UINT32 LineNumber, 1149 UINT32 ComponentId) 1150{ 1151 1152 AcpiOsPrintf ("%8s-%04d: *** Warning: ", ModuleName, LineNumber); 1153} 1154 1155 1156/******************************************************************************* 1157 * 1158 * FUNCTION: _ReportInfo 1159 * 1160 * PARAMETERS: ModuleName - Caller's module name (for error output) 1161 * LineNumber - Caller's line number (for error output) 1162 * ComponentId - Caller's component ID (for error output) 1163 * Message - Error message to use on failure 1164 * 1165 * RETURN: None 1166 * 1167 * DESCRIPTION: Print information message 1168 * 1169 ******************************************************************************/ 1170 1171void 1172_ReportInfo ( 1173 NATIVE_CHAR *ModuleName, 1174 UINT32 LineNumber, 1175 UINT32 ComponentId) 1176{ 1177 1178 AcpiOsPrintf ("%8s-%04d: *** Info: ", ModuleName, LineNumber); 1179} 1180 1181 1182