Home | History | Annotate | Line # | Download | only in utilities
utmisc.c revision 1.3.8.2
      1 /*******************************************************************************
      2  *
      3  * Module Name: utmisc - common utility procedures
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2011, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 
     45 #define __UTMISC_C__
     46 
     47 #include "acpi.h"
     48 #include "accommon.h"
     49 #include "acnamesp.h"
     50 
     51 
     52 #define _COMPONENT          ACPI_UTILITIES
     53         ACPI_MODULE_NAME    ("utmisc")
     54 
     55 
     56 /*******************************************************************************
     57  *
     58  * FUNCTION:    AcpiUtValidateException
     59  *
     60  * PARAMETERS:  Status       - The ACPI_STATUS code to be formatted
     61  *
     62  * RETURN:      A string containing the exception text. NULL if exception is
     63  *              not valid.
     64  *
     65  * DESCRIPTION: This function validates and translates an ACPI exception into
     66  *              an ASCII string.
     67  *
     68  ******************************************************************************/
     69 
     70 const char *
     71 AcpiUtValidateException (
     72     ACPI_STATUS             Status)
     73 {
     74     UINT32                  SubStatus;
     75     const char              *Exception = NULL;
     76 
     77 
     78     ACPI_FUNCTION_ENTRY ();
     79 
     80 
     81     /*
     82      * Status is composed of two parts, a "type" and an actual code
     83      */
     84     SubStatus = (Status & ~AE_CODE_MASK);
     85 
     86     switch (Status & AE_CODE_MASK)
     87     {
     88     case AE_CODE_ENVIRONMENTAL:
     89 
     90         if (SubStatus <= AE_CODE_ENV_MAX)
     91         {
     92             Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
     93         }
     94         break;
     95 
     96     case AE_CODE_PROGRAMMER:
     97 
     98         if (SubStatus <= AE_CODE_PGM_MAX)
     99         {
    100             Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
    101         }
    102         break;
    103 
    104     case AE_CODE_ACPI_TABLES:
    105 
    106         if (SubStatus <= AE_CODE_TBL_MAX)
    107         {
    108             Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
    109         }
    110         break;
    111 
    112     case AE_CODE_AML:
    113 
    114         if (SubStatus <= AE_CODE_AML_MAX)
    115         {
    116             Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
    117         }
    118         break;
    119 
    120     case AE_CODE_CONTROL:
    121 
    122         if (SubStatus <= AE_CODE_CTRL_MAX)
    123         {
    124             Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
    125         }
    126         break;
    127 
    128     default:
    129         break;
    130     }
    131 
    132     return (ACPI_CAST_PTR (const char, Exception));
    133 }
    134 
    135 
    136 /*******************************************************************************
    137  *
    138  * FUNCTION:    AcpiUtIsPciRootBridge
    139  *
    140  * PARAMETERS:  Id              - The HID/CID in string format
    141  *
    142  * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
    143  *
    144  * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
    145  *
    146  ******************************************************************************/
    147 
    148 BOOLEAN
    149 AcpiUtIsPciRootBridge (
    150     char                    *Id)
    151 {
    152 
    153     /*
    154      * Check if this is a PCI root bridge.
    155      * ACPI 3.0+: check for a PCI Express root also.
    156      */
    157     if (!(ACPI_STRCMP (Id,
    158             PCI_ROOT_HID_STRING)) ||
    159 
    160         !(ACPI_STRCMP (Id,
    161             PCI_EXPRESS_ROOT_HID_STRING)))
    162     {
    163         return (TRUE);
    164     }
    165 
    166     return (FALSE);
    167 }
    168 
    169 
    170 /*******************************************************************************
    171  *
    172  * FUNCTION:    AcpiUtIsAmlTable
    173  *
    174  * PARAMETERS:  Table               - An ACPI table
    175  *
    176  * RETURN:      TRUE if table contains executable AML; FALSE otherwise
    177  *
    178  * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
    179  *              Currently, these are DSDT,SSDT,PSDT. All other table types are
    180  *              data tables that do not contain AML code.
    181  *
    182  ******************************************************************************/
    183 
    184 BOOLEAN
    185 AcpiUtIsAmlTable (
    186     ACPI_TABLE_HEADER       *Table)
    187 {
    188 
    189     /* These are the only tables that contain executable AML */
    190 
    191     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
    192         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
    193         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
    194     {
    195         return (TRUE);
    196     }
    197 
    198     return (FALSE);
    199 }
    200 
    201 
    202 /*******************************************************************************
    203  *
    204  * FUNCTION:    AcpiUtAllocateOwnerId
    205  *
    206  * PARAMETERS:  OwnerId         - Where the new owner ID is returned
    207  *
    208  * RETURN:      Status
    209  *
    210  * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
    211  *              track objects created by the table or method, to be deleted
    212  *              when the method exits or the table is unloaded.
    213  *
    214  ******************************************************************************/
    215 
    216 ACPI_STATUS
    217 AcpiUtAllocateOwnerId (
    218     ACPI_OWNER_ID           *OwnerId)
    219 {
    220     UINT32                  i;
    221     UINT32                  j;
    222     UINT32                  k;
    223     ACPI_STATUS             Status;
    224 
    225 
    226     ACPI_FUNCTION_TRACE (UtAllocateOwnerId);
    227 
    228 
    229     /* Guard against multiple allocations of ID to the same location */
    230 
    231     if (*OwnerId)
    232     {
    233         ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId));
    234         return_ACPI_STATUS (AE_ALREADY_EXISTS);
    235     }
    236 
    237     /* Mutex for the global ID mask */
    238 
    239     Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
    240     if (ACPI_FAILURE (Status))
    241     {
    242         return_ACPI_STATUS (Status);
    243     }
    244 
    245     /*
    246      * Find a free owner ID, cycle through all possible IDs on repeated
    247      * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
    248      * to be scanned twice.
    249      */
    250     for (i = 0, j = AcpiGbl_LastOwnerIdIndex;
    251          i < (ACPI_NUM_OWNERID_MASKS + 1);
    252          i++, j++)
    253     {
    254         if (j >= ACPI_NUM_OWNERID_MASKS)
    255         {
    256             j = 0;  /* Wraparound to start of mask array */
    257         }
    258 
    259         for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++)
    260         {
    261             if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX)
    262             {
    263                 /* There are no free IDs in this mask */
    264 
    265                 break;
    266             }
    267 
    268             if (!(AcpiGbl_OwnerIdMask[j] & (1 << k)))
    269             {
    270                 /*
    271                  * Found a free ID. The actual ID is the bit index plus one,
    272                  * making zero an invalid Owner ID. Save this as the last ID
    273                  * allocated and update the global ID mask.
    274                  */
    275                 AcpiGbl_OwnerIdMask[j] |= (1 << k);
    276 
    277                 AcpiGbl_LastOwnerIdIndex = (UINT8) j;
    278                 AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1);
    279 
    280                 /*
    281                  * Construct encoded ID from the index and bit position
    282                  *
    283                  * Note: Last [j].k (bit 255) is never used and is marked
    284                  * permanently allocated (prevents +1 overflow)
    285                  */
    286                 *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j));
    287 
    288                 ACPI_DEBUG_PRINT ((ACPI_DB_VALUES,
    289                     "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId));
    290                 goto Exit;
    291             }
    292         }
    293 
    294         AcpiGbl_NextOwnerIdOffset = 0;
    295     }
    296 
    297     /*
    298      * All OwnerIds have been allocated. This typically should
    299      * not happen since the IDs are reused after deallocation. The IDs are
    300      * allocated upon table load (one per table) and method execution, and
    301      * they are released when a table is unloaded or a method completes
    302      * execution.
    303      *
    304      * If this error happens, there may be very deep nesting of invoked control
    305      * methods, or there may be a bug where the IDs are not released.
    306      */
    307     Status = AE_OWNER_ID_LIMIT;
    308     ACPI_ERROR ((AE_INFO,
    309         "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
    310 
    311 Exit:
    312     (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
    313     return_ACPI_STATUS (Status);
    314 }
    315 
    316 
    317 /*******************************************************************************
    318  *
    319  * FUNCTION:    AcpiUtReleaseOwnerId
    320  *
    321  * PARAMETERS:  OwnerIdPtr          - Pointer to a previously allocated OwnerID
    322  *
    323  * RETURN:      None. No error is returned because we are either exiting a
    324  *              control method or unloading a table. Either way, we would
    325  *              ignore any error anyway.
    326  *
    327  * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 255
    328  *
    329  ******************************************************************************/
    330 
    331 void
    332 AcpiUtReleaseOwnerId (
    333     ACPI_OWNER_ID           *OwnerIdPtr)
    334 {
    335     ACPI_OWNER_ID           OwnerId = *OwnerIdPtr;
    336     ACPI_STATUS             Status;
    337     UINT32                  Index;
    338     UINT32                  Bit;
    339 
    340 
    341     ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId);
    342 
    343 
    344     /* Always clear the input OwnerId (zero is an invalid ID) */
    345 
    346     *OwnerIdPtr = 0;
    347 
    348     /* Zero is not a valid OwnerID */
    349 
    350     if (OwnerId == 0)
    351     {
    352         ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId));
    353         return_VOID;
    354     }
    355 
    356     /* Mutex for the global ID mask */
    357 
    358     Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
    359     if (ACPI_FAILURE (Status))
    360     {
    361         return_VOID;
    362     }
    363 
    364     /* Normalize the ID to zero */
    365 
    366     OwnerId--;
    367 
    368     /* Decode ID to index/offset pair */
    369 
    370     Index = ACPI_DIV_32 (OwnerId);
    371     Bit = 1 << ACPI_MOD_32 (OwnerId);
    372 
    373     /* Free the owner ID only if it is valid */
    374 
    375     if (AcpiGbl_OwnerIdMask[Index] & Bit)
    376     {
    377         AcpiGbl_OwnerIdMask[Index] ^= Bit;
    378     }
    379     else
    380     {
    381         ACPI_ERROR ((AE_INFO,
    382             "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1));
    383     }
    384 
    385     (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
    386     return_VOID;
    387 }
    388 
    389 
    390 /*******************************************************************************
    391  *
    392  * FUNCTION:    AcpiUtStrupr (strupr)
    393  *
    394  * PARAMETERS:  SrcString       - The source string to convert
    395  *
    396  * RETURN:      None
    397  *
    398  * DESCRIPTION: Convert string to uppercase
    399  *
    400  * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
    401  *
    402  ******************************************************************************/
    403 
    404 void
    405 AcpiUtStrupr (
    406     char                    *SrcString)
    407 {
    408     char                    *String;
    409 
    410 
    411     ACPI_FUNCTION_ENTRY ();
    412 
    413 
    414     if (!SrcString)
    415     {
    416         return;
    417     }
    418 
    419     /* Walk entire string, uppercasing the letters */
    420 
    421     for (String = SrcString; *String; String++)
    422     {
    423         *String = (char) ACPI_TOUPPER (*String);
    424     }
    425 
    426     return;
    427 }
    428 
    429 
    430 #ifdef ACPI_ASL_COMPILER
    431 /*******************************************************************************
    432  *
    433  * FUNCTION:    AcpiUtStrlwr (strlwr)
    434  *
    435  * PARAMETERS:  SrcString       - The source string to convert
    436  *
    437  * RETURN:      None
    438  *
    439  * DESCRIPTION: Convert string to lowercase
    440  *
    441  * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
    442  *
    443  ******************************************************************************/
    444 
    445 void
    446 AcpiUtStrlwr (
    447     char                    *SrcString)
    448 {
    449     char                    *String;
    450 
    451 
    452     ACPI_FUNCTION_ENTRY ();
    453 
    454 
    455     if (!SrcString)
    456     {
    457         return;
    458     }
    459 
    460     /* Walk entire string, lowercasing the letters */
    461 
    462     for (String = SrcString; *String; String++)
    463     {
    464         *String = (char) ACPI_TOLOWER (*String);
    465     }
    466 
    467     return;
    468 }
    469 #endif
    470 
    471 
    472 /*******************************************************************************
    473  *
    474  * FUNCTION:    AcpiUtPrintString
    475  *
    476  * PARAMETERS:  String          - Null terminated ASCII string
    477  *              MaxLength       - Maximum output length
    478  *
    479  * RETURN:      None
    480  *
    481  * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
    482  *              sequences.
    483  *
    484  ******************************************************************************/
    485 
    486 void
    487 AcpiUtPrintString (
    488     char                    *String,
    489     UINT8                   MaxLength)
    490 {
    491     UINT32                  i;
    492 
    493 
    494     if (!String)
    495     {
    496         AcpiOsPrintf ("<\"NULL STRING PTR\">");
    497         return;
    498     }
    499 
    500     AcpiOsPrintf ("\"");
    501     for (i = 0; String[i] && (i < MaxLength); i++)
    502     {
    503         /* Escape sequences */
    504 
    505         switch (String[i])
    506         {
    507         case 0x07:
    508             AcpiOsPrintf ("\\a");       /* BELL */
    509             break;
    510 
    511         case 0x08:
    512             AcpiOsPrintf ("\\b");       /* BACKSPACE */
    513             break;
    514 
    515         case 0x0C:
    516             AcpiOsPrintf ("\\f");       /* FORMFEED */
    517             break;
    518 
    519         case 0x0A:
    520             AcpiOsPrintf ("\\n");       /* LINEFEED */
    521             break;
    522 
    523         case 0x0D:
    524             AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
    525             break;
    526 
    527         case 0x09:
    528             AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
    529             break;
    530 
    531         case 0x0B:
    532             AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
    533             break;
    534 
    535         case '\'':                      /* Single Quote */
    536         case '\"':                      /* Double Quote */
    537         case '\\':                      /* Backslash */
    538             AcpiOsPrintf ("\\%c", (int) String[i]);
    539             break;
    540 
    541         default:
    542 
    543             /* Check for printable character or hex escape */
    544 
    545             if (ACPI_IS_PRINT (String[i]))
    546             {
    547                 /* This is a normal character */
    548 
    549                 AcpiOsPrintf ("%c", (int) String[i]);
    550             }
    551             else
    552             {
    553                 /* All others will be Hex escapes */
    554 
    555                 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
    556             }
    557             break;
    558         }
    559     }
    560     AcpiOsPrintf ("\"");
    561 
    562     if (i == MaxLength && String[i])
    563     {
    564         AcpiOsPrintf ("...");
    565     }
    566 }
    567 
    568 
    569 /*******************************************************************************
    570  *
    571  * FUNCTION:    AcpiUtDwordByteSwap
    572  *
    573  * PARAMETERS:  Value           - Value to be converted
    574  *
    575  * RETURN:      UINT32 integer with bytes swapped
    576  *
    577  * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
    578  *
    579  ******************************************************************************/
    580 
    581 UINT32
    582 AcpiUtDwordByteSwap (
    583     UINT32                  Value)
    584 {
    585     union
    586     {
    587         UINT32              Value;
    588         UINT8               Bytes[4];
    589     } Out;
    590     union
    591     {
    592         UINT32              Value;
    593         UINT8               Bytes[4];
    594     } In;
    595 
    596 
    597     ACPI_FUNCTION_ENTRY ();
    598 
    599 
    600     In.Value = Value;
    601 
    602     Out.Bytes[0] = In.Bytes[3];
    603     Out.Bytes[1] = In.Bytes[2];
    604     Out.Bytes[2] = In.Bytes[1];
    605     Out.Bytes[3] = In.Bytes[0];
    606 
    607     return (Out.Value);
    608 }
    609 
    610 
    611 /*******************************************************************************
    612  *
    613  * FUNCTION:    AcpiUtSetIntegerWidth
    614  *
    615  * PARAMETERS:  Revision            From DSDT header
    616  *
    617  * RETURN:      None
    618  *
    619  * DESCRIPTION: Set the global integer bit width based upon the revision
    620  *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
    621  *              For Revision 2 and above, Integers are 64 bits.  Yes, this
    622  *              makes a difference.
    623  *
    624  ******************************************************************************/
    625 
    626 void
    627 AcpiUtSetIntegerWidth (
    628     UINT8                   Revision)
    629 {
    630 
    631     if (Revision < 2)
    632     {
    633         /* 32-bit case */
    634 
    635         AcpiGbl_IntegerBitWidth    = 32;
    636         AcpiGbl_IntegerNybbleWidth = 8;
    637         AcpiGbl_IntegerByteWidth   = 4;
    638     }
    639     else
    640     {
    641         /* 64-bit case (ACPI 2.0+) */
    642 
    643         AcpiGbl_IntegerBitWidth    = 64;
    644         AcpiGbl_IntegerNybbleWidth = 16;
    645         AcpiGbl_IntegerByteWidth   = 8;
    646     }
    647 }
    648 
    649 
    650 #ifdef ACPI_DEBUG_OUTPUT
    651 /*******************************************************************************
    652  *
    653  * FUNCTION:    AcpiUtDisplayInitPathname
    654  *
    655  * PARAMETERS:  Type                - Object type of the node
    656  *              ObjHandle           - Handle whose pathname will be displayed
    657  *              Path                - Additional path string to be appended.
    658  *                                      (NULL if no extra path)
    659  *
    660  * RETURN:      ACPI_STATUS
    661  *
    662  * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
    663  *
    664  ******************************************************************************/
    665 
    666 void
    667 AcpiUtDisplayInitPathname (
    668     UINT8                   Type,
    669     ACPI_NAMESPACE_NODE     *ObjHandle,
    670     const char              *Path)
    671 {
    672     ACPI_STATUS             Status;
    673     ACPI_BUFFER             Buffer;
    674 
    675 
    676     ACPI_FUNCTION_ENTRY ();
    677 
    678 
    679     /* Only print the path if the appropriate debug level is enabled */
    680 
    681     if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
    682     {
    683         return;
    684     }
    685 
    686     /* Get the full pathname to the node */
    687 
    688     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    689     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
    690     if (ACPI_FAILURE (Status))
    691     {
    692         return;
    693     }
    694 
    695     /* Print what we're doing */
    696 
    697     switch (Type)
    698     {
    699     case ACPI_TYPE_METHOD:
    700         AcpiOsPrintf ("Executing    ");
    701         break;
    702 
    703     default:
    704         AcpiOsPrintf ("Initializing ");
    705         break;
    706     }
    707 
    708     /* Print the object type and pathname */
    709 
    710     AcpiOsPrintf ("%-12s  %s",
    711         AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
    712 
    713     /* Extra path is used to append names like _STA, _INI, etc. */
    714 
    715     if (Path)
    716     {
    717         AcpiOsPrintf (".%s", Path);
    718     }
    719     AcpiOsPrintf ("\n");
    720 
    721     ACPI_FREE (Buffer.Pointer);
    722 }
    723 #endif
    724 
    725 
    726 /*******************************************************************************
    727  *
    728  * FUNCTION:    AcpiUtValidAcpiChar
    729  *
    730  * PARAMETERS:  Char            - The character to be examined
    731  *              Position        - Byte position (0-3)
    732  *
    733  * RETURN:      TRUE if the character is valid, FALSE otherwise
    734  *
    735  * DESCRIPTION: Check for a valid ACPI character. Must be one of:
    736  *              1) Upper case alpha
    737  *              2) numeric
    738  *              3) underscore
    739  *
    740  *              We allow a '!' as the last character because of the ASF! table
    741  *
    742  ******************************************************************************/
    743 
    744 BOOLEAN
    745 AcpiUtValidAcpiChar (
    746     char                    Character,
    747     UINT32                  Position)
    748 {
    749 
    750     if (!((Character >= 'A' && Character <= 'Z') ||
    751           (Character >= '0' && Character <= '9') ||
    752           (Character == '_')))
    753     {
    754         /* Allow a '!' in the last position */
    755 
    756         if (Character == '!' && Position == 3)
    757         {
    758             return (TRUE);
    759         }
    760 
    761         return (FALSE);
    762     }
    763 
    764     return (TRUE);
    765 }
    766 
    767 
    768 /*******************************************************************************
    769  *
    770  * FUNCTION:    AcpiUtValidAcpiName
    771  *
    772  * PARAMETERS:  Name            - The name to be examined
    773  *
    774  * RETURN:      TRUE if the name is valid, FALSE otherwise
    775  *
    776  * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
    777  *              1) Upper case alpha
    778  *              2) numeric
    779  *              3) underscore
    780  *
    781  ******************************************************************************/
    782 
    783 BOOLEAN
    784 AcpiUtValidAcpiName (
    785     UINT32                  Name)
    786 {
    787     UINT32                  i;
    788 
    789 
    790     ACPI_FUNCTION_ENTRY ();
    791 
    792 
    793     for (i = 0; i < ACPI_NAME_SIZE; i++)
    794     {
    795         if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i))
    796         {
    797             return (FALSE);
    798         }
    799     }
    800 
    801     return (TRUE);
    802 }
    803 
    804 
    805 /*******************************************************************************
    806  *
    807  * FUNCTION:    AcpiUtRepairName
    808  *
    809  * PARAMETERS:  Name            - The ACPI name to be repaired
    810  *
    811  * RETURN:      Repaired version of the name
    812  *
    813  * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
    814  *              return the new name. NOTE: the Name parameter must reside in
    815  *              read/write memory, cannot be a const.
    816  *
    817  * An ACPI Name must consist of valid ACPI characters. We will repair the name
    818  * if necessary because we don't want to abort because of this, but we want
    819  * all namespace names to be printable. A warning message is appropriate.
    820  *
    821  * This issue came up because there are in fact machines that exhibit
    822  * this problem, and we want to be able to enable ACPI support for them,
    823  * even though there are a few bad names.
    824  *
    825  ******************************************************************************/
    826 
    827 void
    828 AcpiUtRepairName (
    829     char                    *Name)
    830 {
    831     UINT32                  i;
    832     BOOLEAN                 FoundBadChar = FALSE;
    833 
    834 
    835     ACPI_FUNCTION_NAME (UtRepairName);
    836 
    837 
    838     /* Check each character in the name */
    839 
    840     for (i = 0; i < ACPI_NAME_SIZE; i++)
    841     {
    842         if (AcpiUtValidAcpiChar (Name[i], i))
    843         {
    844             continue;
    845         }
    846 
    847         /*
    848          * Replace a bad character with something printable, yet technically
    849          * still invalid. This prevents any collisions with existing "good"
    850          * names in the namespace.
    851          */
    852         Name[i] = '*';
    853         FoundBadChar = TRUE;
    854     }
    855 
    856     if (FoundBadChar)
    857     {
    858         /* Report warning only if in strict mode or debug mode */
    859 
    860         if (!AcpiGbl_EnableInterpreterSlack)
    861         {
    862             ACPI_WARNING ((AE_INFO,
    863                 "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
    864         }
    865         else
    866         {
    867             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    868                 "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
    869         }
    870     }
    871 }
    872 
    873 
    874 /*******************************************************************************
    875  *
    876  * FUNCTION:    AcpiUtStrtoul64
    877  *
    878  * PARAMETERS:  String          - Null terminated string
    879  *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
    880  *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
    881  *              RetInteger      - Where the converted integer is returned
    882  *
    883  * RETURN:      Status and Converted value
    884  *
    885  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
    886  *              32-bit or 64-bit conversion, depending on the current mode
    887  *              of the interpreter.
    888  *              NOTE: Does not support Octal strings, not needed.
    889  *
    890  ******************************************************************************/
    891 
    892 ACPI_STATUS
    893 AcpiUtStrtoul64 (
    894     char                    *String,
    895     UINT32                  Base,
    896     UINT64                  *RetInteger)
    897 {
    898     UINT32                  ThisDigit = 0;
    899     UINT64                  ReturnValue = 0;
    900     UINT64                  Quotient;
    901     UINT64                  Dividend;
    902     UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
    903     UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
    904     UINT8                   ValidDigits = 0;
    905     UINT8                   SignOf0x = 0;
    906     UINT8                   Term = 0;
    907 
    908 
    909     ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
    910 
    911 
    912     switch (Base)
    913     {
    914     case ACPI_ANY_BASE:
    915     case 16:
    916         break;
    917 
    918     default:
    919         /* Invalid Base */
    920         return_ACPI_STATUS (AE_BAD_PARAMETER);
    921     }
    922 
    923     if (!String)
    924     {
    925         goto ErrorExit;
    926     }
    927 
    928     /* Skip over any white space in the buffer */
    929 
    930     while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
    931     {
    932         String++;
    933     }
    934 
    935     if (ToIntegerOp)
    936     {
    937         /*
    938          * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
    939          * We need to determine if it is decimal or hexadecimal.
    940          */
    941         if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
    942         {
    943             SignOf0x = 1;
    944             Base = 16;
    945 
    946             /* Skip over the leading '0x' */
    947             String += 2;
    948         }
    949         else
    950         {
    951             Base = 10;
    952         }
    953     }
    954 
    955     /* Any string left? Check that '0x' is not followed by white space. */
    956 
    957     if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
    958     {
    959         if (ToIntegerOp)
    960         {
    961             goto ErrorExit;
    962         }
    963         else
    964         {
    965             goto AllDone;
    966         }
    967     }
    968 
    969     /*
    970      * Perform a 32-bit or 64-bit conversion, depending upon the current
    971      * execution mode of the interpreter
    972      */
    973     Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
    974 
    975     /* Main loop: convert the string to a 32- or 64-bit integer */
    976 
    977     while (*String)
    978     {
    979         if (ACPI_IS_DIGIT (*String))
    980         {
    981             /* Convert ASCII 0-9 to Decimal value */
    982 
    983             ThisDigit = ((UINT8) *String) - '0';
    984         }
    985         else if (Base == 10)
    986         {
    987             /* Digit is out of range; possible in ToInteger case only */
    988 
    989             Term = 1;
    990         }
    991         else
    992         {
    993             ThisDigit = (UINT8) ACPI_TOUPPER (*String);
    994             if (ACPI_IS_XDIGIT ((char) ThisDigit))
    995             {
    996                 /* Convert ASCII Hex char to value */
    997 
    998                 ThisDigit = ThisDigit - 'A' + 10;
    999             }
   1000             else
   1001             {
   1002                 Term = 1;
   1003             }
   1004         }
   1005 
   1006         if (Term)
   1007         {
   1008             if (ToIntegerOp)
   1009             {
   1010                 goto ErrorExit;
   1011             }
   1012             else
   1013             {
   1014                 break;
   1015             }
   1016         }
   1017         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
   1018         {
   1019             /* Skip zeros */
   1020             String++;
   1021             continue;
   1022         }
   1023 
   1024         ValidDigits++;
   1025 
   1026         if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
   1027         {
   1028             /*
   1029              * This is ToInteger operation case.
   1030              * No any restrictions for string-to-integer conversion,
   1031              * see ACPI spec.
   1032              */
   1033             goto ErrorExit;
   1034         }
   1035 
   1036         /* Divide the digit into the correct position */
   1037 
   1038         (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
   1039                     Base, &Quotient, NULL);
   1040 
   1041         if (ReturnValue > Quotient)
   1042         {
   1043             if (ToIntegerOp)
   1044             {
   1045                 goto ErrorExit;
   1046             }
   1047             else
   1048             {
   1049                 break;
   1050             }
   1051         }
   1052 
   1053         ReturnValue *= Base;
   1054         ReturnValue += ThisDigit;
   1055         String++;
   1056     }
   1057 
   1058     /* All done, normal exit */
   1059 
   1060 AllDone:
   1061 
   1062     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
   1063         ACPI_FORMAT_UINT64 (ReturnValue)));
   1064 
   1065     *RetInteger = ReturnValue;
   1066     return_ACPI_STATUS (AE_OK);
   1067 
   1068 
   1069 ErrorExit:
   1070     /* Base was set/validated above */
   1071 
   1072     if (Base == 10)
   1073     {
   1074         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
   1075     }
   1076     else
   1077     {
   1078         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
   1079     }
   1080 }
   1081 
   1082 
   1083 /*******************************************************************************
   1084  *
   1085  * FUNCTION:    AcpiUtCreateUpdateStateAndPush
   1086  *
   1087  * PARAMETERS:  Object          - Object to be added to the new state
   1088  *              Action          - Increment/Decrement
   1089  *              StateList       - List the state will be added to
   1090  *
   1091  * RETURN:      Status
   1092  *
   1093  * DESCRIPTION: Create a new state and push it
   1094  *
   1095  ******************************************************************************/
   1096 
   1097 ACPI_STATUS
   1098 AcpiUtCreateUpdateStateAndPush (
   1099     ACPI_OPERAND_OBJECT     *Object,
   1100     UINT16                  Action,
   1101     ACPI_GENERIC_STATE      **StateList)
   1102 {
   1103     ACPI_GENERIC_STATE       *State;
   1104 
   1105 
   1106     ACPI_FUNCTION_ENTRY ();
   1107 
   1108 
   1109     /* Ignore null objects; these are expected */
   1110 
   1111     if (!Object)
   1112     {
   1113         return (AE_OK);
   1114     }
   1115 
   1116     State = AcpiUtCreateUpdateState (Object, Action);
   1117     if (!State)
   1118     {
   1119         return (AE_NO_MEMORY);
   1120     }
   1121 
   1122     AcpiUtPushGenericState (StateList, State);
   1123     return (AE_OK);
   1124 }
   1125 
   1126 
   1127 /*******************************************************************************
   1128  *
   1129  * FUNCTION:    AcpiUtWalkPackageTree
   1130  *
   1131  * PARAMETERS:  SourceObject        - The package to walk
   1132  *              TargetObject        - Target object (if package is being copied)
   1133  *              WalkCallback        - Called once for each package element
   1134  *              Context             - Passed to the callback function
   1135  *
   1136  * RETURN:      Status
   1137  *
   1138  * DESCRIPTION: Walk through a package
   1139  *
   1140  ******************************************************************************/
   1141 
   1142 ACPI_STATUS
   1143 AcpiUtWalkPackageTree (
   1144     ACPI_OPERAND_OBJECT     *SourceObject,
   1145     void                    *TargetObject,
   1146     ACPI_PKG_CALLBACK       WalkCallback,
   1147     void                    *Context)
   1148 {
   1149     ACPI_STATUS             Status = AE_OK;
   1150     ACPI_GENERIC_STATE      *StateList = NULL;
   1151     ACPI_GENERIC_STATE      *State;
   1152     UINT32                  ThisIndex;
   1153     ACPI_OPERAND_OBJECT     *ThisSourceObj;
   1154 
   1155 
   1156     ACPI_FUNCTION_TRACE (UtWalkPackageTree);
   1157 
   1158 
   1159     State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
   1160     if (!State)
   1161     {
   1162         return_ACPI_STATUS (AE_NO_MEMORY);
   1163     }
   1164 
   1165     while (State)
   1166     {
   1167         /* Get one element of the package */
   1168 
   1169         ThisIndex     = State->Pkg.Index;
   1170         ThisSourceObj = (ACPI_OPERAND_OBJECT *)
   1171                         State->Pkg.SourceObject->Package.Elements[ThisIndex];
   1172 
   1173         /*
   1174          * Check for:
   1175          * 1) An uninitialized package element.  It is completely
   1176          *    legal to declare a package and leave it uninitialized
   1177          * 2) Not an internal object - can be a namespace node instead
   1178          * 3) Any type other than a package.  Packages are handled in else
   1179          *    case below.
   1180          */
   1181         if ((!ThisSourceObj) ||
   1182             (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
   1183             (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
   1184         {
   1185             Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
   1186                                     State, Context);
   1187             if (ACPI_FAILURE (Status))
   1188             {
   1189                 return_ACPI_STATUS (Status);
   1190             }
   1191 
   1192             State->Pkg.Index++;
   1193             while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
   1194             {
   1195                 /*
   1196                  * We've handled all of the objects at this level,  This means
   1197                  * that we have just completed a package.  That package may
   1198                  * have contained one or more packages itself.
   1199                  *
   1200                  * Delete this state and pop the previous state (package).
   1201                  */
   1202                 AcpiUtDeleteGenericState (State);
   1203                 State = AcpiUtPopGenericState (&StateList);
   1204 
   1205                 /* Finished when there are no more states */
   1206 
   1207                 if (!State)
   1208                 {
   1209                     /*
   1210                      * We have handled all of the objects in the top level
   1211                      * package just add the length of the package objects
   1212                      * and exit
   1213                      */
   1214                     return_ACPI_STATUS (AE_OK);
   1215                 }
   1216 
   1217                 /*
   1218                  * Go back up a level and move the index past the just
   1219                  * completed package object.
   1220                  */
   1221                 State->Pkg.Index++;
   1222             }
   1223         }
   1224         else
   1225         {
   1226             /* This is a subobject of type package */
   1227 
   1228             Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
   1229                                         State, Context);
   1230             if (ACPI_FAILURE (Status))
   1231             {
   1232                 return_ACPI_STATUS (Status);
   1233             }
   1234 
   1235             /*
   1236              * Push the current state and create a new one
   1237              * The callback above returned a new target package object.
   1238              */
   1239             AcpiUtPushGenericState (&StateList, State);
   1240             State = AcpiUtCreatePkgState (ThisSourceObj,
   1241                                             State->Pkg.ThisTargetObj, 0);
   1242             if (!State)
   1243             {
   1244                 /* Free any stacked Update State objects */
   1245 
   1246                 while (StateList)
   1247                 {
   1248                     State = AcpiUtPopGenericState (&StateList);
   1249                     AcpiUtDeleteGenericState (State);
   1250                 }
   1251                 return_ACPI_STATUS (AE_NO_MEMORY);
   1252             }
   1253         }
   1254     }
   1255 
   1256     /* We should never get here */
   1257 
   1258     return_ACPI_STATUS (AE_AML_INTERNAL);
   1259 }
   1260 
   1261 
   1262