13446Smrj /*******************************************************************************
23446Smrj  *
33446Smrj  * Module Name: utmisc - common utility procedures
43446Smrj  *
53446Smrj  ******************************************************************************/
63446Smrj 
73446Smrj /******************************************************************************
83446Smrj  *
93446Smrj  * 1. Copyright Notice
103446Smrj  *
11*9980SDana.Myers@Sun.COM  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
123446Smrj  * All rights reserved.
133446Smrj  *
143446Smrj  * 2. License
153446Smrj  *
163446Smrj  * 2.1. This is your license from Intel Corp. under its intellectual property
173446Smrj  * rights.  You may have additional license terms from the party that provided
183446Smrj  * you this software, covering your right to use that party's intellectual
193446Smrj  * property rights.
203446Smrj  *
213446Smrj  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
223446Smrj  * copy of the source code appearing in this file ("Covered Code") an
233446Smrj  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
243446Smrj  * base code distributed originally by Intel ("Original Intel Code") to copy,
253446Smrj  * make derivatives, distribute, use and display any portion of the Covered
263446Smrj  * Code in any form, with the right to sublicense such rights; and
273446Smrj  *
283446Smrj  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
293446Smrj  * license (with the right to sublicense), under only those claims of Intel
303446Smrj  * patents that are infringed by the Original Intel Code, to make, use, sell,
313446Smrj  * offer to sell, and import the Covered Code and derivative works thereof
323446Smrj  * solely to the minimum extent necessary to exercise the above copyright
333446Smrj  * license, and in no event shall the patent license extend to any additions
343446Smrj  * to or modifications of the Original Intel Code.  No other license or right
353446Smrj  * is granted directly or by implication, estoppel or otherwise;
363446Smrj  *
373446Smrj  * The above copyright and patent license is granted only if the following
383446Smrj  * conditions are met:
393446Smrj  *
403446Smrj  * 3. Conditions
413446Smrj  *
423446Smrj  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
433446Smrj  * Redistribution of source code of any substantial portion of the Covered
443446Smrj  * Code or modification with rights to further distribute source must include
453446Smrj  * the above Copyright Notice, the above License, this list of Conditions,
463446Smrj  * and the following Disclaimer and Export Compliance provision.  In addition,
473446Smrj  * Licensee must cause all Covered Code to which Licensee contributes to
483446Smrj  * contain a file documenting the changes Licensee made to create that Covered
493446Smrj  * Code and the date of any change.  Licensee must include in that file the
503446Smrj  * documentation of any changes made by any predecessor Licensee.  Licensee
513446Smrj  * must include a prominent statement that the modification is derived,
523446Smrj  * directly or indirectly, from Original Intel Code.
533446Smrj  *
543446Smrj  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
553446Smrj  * Redistribution of source code of any substantial portion of the Covered
563446Smrj  * Code or modification without rights to further distribute source must
573446Smrj  * include the following Disclaimer and Export Compliance provision in the
583446Smrj  * documentation and/or other materials provided with distribution.  In
593446Smrj  * addition, Licensee may not authorize further sublicense of source of any
603446Smrj  * portion of the Covered Code, and must include terms to the effect that the
613446Smrj  * license from Licensee to its licensee is limited to the intellectual
623446Smrj  * property embodied in the software Licensee provides to its licensee, and
633446Smrj  * not to intellectual property embodied in modifications its licensee may
643446Smrj  * make.
653446Smrj  *
663446Smrj  * 3.3. Redistribution of Executable. Redistribution in executable form of any
673446Smrj  * substantial portion of the Covered Code or modification must reproduce the
683446Smrj  * above Copyright Notice, and the following Disclaimer and Export Compliance
693446Smrj  * provision in the documentation and/or other materials provided with the
703446Smrj  * distribution.
713446Smrj  *
723446Smrj  * 3.4. Intel retains all right, title, and interest in and to the Original
733446Smrj  * Intel Code.
743446Smrj  *
753446Smrj  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
763446Smrj  * Intel shall be used in advertising or otherwise to promote the sale, use or
773446Smrj  * other dealings in products derived from or relating to the Covered Code
783446Smrj  * without prior written authorization from Intel.
793446Smrj  *
803446Smrj  * 4. Disclaimer and Export Compliance
813446Smrj  *
823446Smrj  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
833446Smrj  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
843446Smrj  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
853446Smrj  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
863446Smrj  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
873446Smrj  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
883446Smrj  * PARTICULAR PURPOSE.
893446Smrj  *
903446Smrj  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
913446Smrj  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
923446Smrj  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
933446Smrj  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
943446Smrj  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
953446Smrj  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
963446Smrj  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
973446Smrj  * LIMITED REMEDY.
983446Smrj  *
993446Smrj  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1003446Smrj  * software or system incorporating such software without first obtaining any
1013446Smrj  * required license or other approval from the U. S. Department of Commerce or
1023446Smrj  * any other agency or department of the United States Government.  In the
1033446Smrj  * event Licensee exports any such software from the United States or
1043446Smrj  * re-exports any such software from a foreign destination, Licensee shall
1053446Smrj  * ensure that the distribution and export/re-export of the software is in
1063446Smrj  * compliance with all laws, regulations, orders, or other restrictions of the
1073446Smrj  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1083446Smrj  * any of its subsidiaries will export/re-export any technical data, process,
1093446Smrj  * software, or service, directly or indirectly, to any country for which the
1103446Smrj  * United States government or any agency thereof requires an export license,
1113446Smrj  * other governmental approval, or letter of assurance, without first obtaining
1123446Smrj  * such license, approval or letter.
1133446Smrj  *
1143446Smrj  *****************************************************************************/
1153446Smrj 
1163446Smrj 
1173446Smrj #define __UTMISC_C__
1183446Smrj 
1193446Smrj #include "acpi.h"
120*9980SDana.Myers@Sun.COM #include "accommon.h"
1213446Smrj #include "acnamesp.h"
1223446Smrj 
1233446Smrj 
1243446Smrj #define _COMPONENT          ACPI_UTILITIES
1253446Smrj         ACPI_MODULE_NAME    ("utmisc")
1263446Smrj 
1273446Smrj 
1283446Smrj /*******************************************************************************
1293446Smrj  *
1307851SDana.Myers@Sun.COM  * FUNCTION:    AcpiUtValidateException
1317851SDana.Myers@Sun.COM  *
1327851SDana.Myers@Sun.COM  * PARAMETERS:  Status       - The ACPI_STATUS code to be formatted
1337851SDana.Myers@Sun.COM  *
1347851SDana.Myers@Sun.COM  * RETURN:      A string containing the exception text. NULL if exception is
1357851SDana.Myers@Sun.COM  *              not valid.
1367851SDana.Myers@Sun.COM  *
1377851SDana.Myers@Sun.COM  * DESCRIPTION: This function validates and translates an ACPI exception into
1387851SDana.Myers@Sun.COM  *              an ASCII string.
1397851SDana.Myers@Sun.COM  *
1407851SDana.Myers@Sun.COM  ******************************************************************************/
1417851SDana.Myers@Sun.COM 
1427851SDana.Myers@Sun.COM const char *
1437851SDana.Myers@Sun.COM AcpiUtValidateException (
1447851SDana.Myers@Sun.COM     ACPI_STATUS             Status)
1457851SDana.Myers@Sun.COM {
1467851SDana.Myers@Sun.COM     UINT32                  SubStatus;
1477851SDana.Myers@Sun.COM     const char              *Exception = NULL;
1487851SDana.Myers@Sun.COM 
1497851SDana.Myers@Sun.COM 
1507851SDana.Myers@Sun.COM     ACPI_FUNCTION_ENTRY ();
1517851SDana.Myers@Sun.COM 
1527851SDana.Myers@Sun.COM 
1537851SDana.Myers@Sun.COM     /*
1547851SDana.Myers@Sun.COM      * Status is composed of two parts, a "type" and an actual code
1557851SDana.Myers@Sun.COM      */
1567851SDana.Myers@Sun.COM     SubStatus = (Status & ~AE_CODE_MASK);
1577851SDana.Myers@Sun.COM 
1587851SDana.Myers@Sun.COM     switch (Status & AE_CODE_MASK)
1597851SDana.Myers@Sun.COM     {
1607851SDana.Myers@Sun.COM     case AE_CODE_ENVIRONMENTAL:
1617851SDana.Myers@Sun.COM 
1627851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_ENV_MAX)
1637851SDana.Myers@Sun.COM         {
1647851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
1657851SDana.Myers@Sun.COM         }
1667851SDana.Myers@Sun.COM         break;
1677851SDana.Myers@Sun.COM 
1687851SDana.Myers@Sun.COM     case AE_CODE_PROGRAMMER:
1697851SDana.Myers@Sun.COM 
1707851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_PGM_MAX)
1717851SDana.Myers@Sun.COM         {
1727851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
1737851SDana.Myers@Sun.COM         }
1747851SDana.Myers@Sun.COM         break;
1757851SDana.Myers@Sun.COM 
1767851SDana.Myers@Sun.COM     case AE_CODE_ACPI_TABLES:
1777851SDana.Myers@Sun.COM 
1787851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_TBL_MAX)
1797851SDana.Myers@Sun.COM         {
1807851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
1817851SDana.Myers@Sun.COM         }
1827851SDana.Myers@Sun.COM         break;
1837851SDana.Myers@Sun.COM 
1847851SDana.Myers@Sun.COM     case AE_CODE_AML:
1857851SDana.Myers@Sun.COM 
1867851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_AML_MAX)
1877851SDana.Myers@Sun.COM         {
1887851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
1897851SDana.Myers@Sun.COM         }
1907851SDana.Myers@Sun.COM         break;
1917851SDana.Myers@Sun.COM 
1927851SDana.Myers@Sun.COM     case AE_CODE_CONTROL:
1937851SDana.Myers@Sun.COM 
1947851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_CTRL_MAX)
1957851SDana.Myers@Sun.COM         {
1967851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
1977851SDana.Myers@Sun.COM         }
1987851SDana.Myers@Sun.COM         break;
1997851SDana.Myers@Sun.COM 
2007851SDana.Myers@Sun.COM     default:
2017851SDana.Myers@Sun.COM         break;
2027851SDana.Myers@Sun.COM     }
2037851SDana.Myers@Sun.COM 
2047851SDana.Myers@Sun.COM     return (ACPI_CAST_PTR (const char, Exception));
2057851SDana.Myers@Sun.COM }
2067851SDana.Myers@Sun.COM 
2077851SDana.Myers@Sun.COM 
2087851SDana.Myers@Sun.COM /*******************************************************************************
2097851SDana.Myers@Sun.COM  *
2103446Smrj  * FUNCTION:    AcpiUtIsAmlTable
2113446Smrj  *
2123446Smrj  * PARAMETERS:  Table               - An ACPI table
2133446Smrj  *
2143446Smrj  * RETURN:      TRUE if table contains executable AML; FALSE otherwise
2153446Smrj  *
2163446Smrj  * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
2173446Smrj  *              Currently, these are DSDT,SSDT,PSDT. All other table types are
2183446Smrj  *              data tables that do not contain AML code.
2193446Smrj  *
2203446Smrj  ******************************************************************************/
2213446Smrj 
2223446Smrj BOOLEAN
2233446Smrj AcpiUtIsAmlTable (
2243446Smrj     ACPI_TABLE_HEADER       *Table)
2253446Smrj {
2263446Smrj 
2273446Smrj     /* These are the only tables that contain executable AML */
2283446Smrj 
2297851SDana.Myers@Sun.COM     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
2307851SDana.Myers@Sun.COM         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
2317851SDana.Myers@Sun.COM         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
2323446Smrj     {
2333446Smrj         return (TRUE);
2343446Smrj     }
2353446Smrj 
2363446Smrj     return (FALSE);
2373446Smrj }
2383446Smrj 
2393446Smrj 
2403446Smrj /*******************************************************************************
2413446Smrj  *
2423446Smrj  * FUNCTION:    AcpiUtAllocateOwnerId
2433446Smrj  *
2443446Smrj  * PARAMETERS:  OwnerId         - Where the new owner ID is returned
2453446Smrj  *
2463446Smrj  * RETURN:      Status
2473446Smrj  *
2483446Smrj  * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
2493446Smrj  *              track objects created by the table or method, to be deleted
2503446Smrj  *              when the method exits or the table is unloaded.
2513446Smrj  *
2523446Smrj  ******************************************************************************/
2533446Smrj 
2543446Smrj ACPI_STATUS
2553446Smrj AcpiUtAllocateOwnerId (
2563446Smrj     ACPI_OWNER_ID           *OwnerId)
2573446Smrj {
2587851SDana.Myers@Sun.COM     UINT32                  i;
2597851SDana.Myers@Sun.COM     UINT32                  j;
2607851SDana.Myers@Sun.COM     UINT32                  k;
2613446Smrj     ACPI_STATUS             Status;
2623446Smrj 
2633446Smrj 
2643446Smrj     ACPI_FUNCTION_TRACE (UtAllocateOwnerId);
2653446Smrj 
2663446Smrj 
2673446Smrj     /* Guard against multiple allocations of ID to the same location */
2683446Smrj 
2693446Smrj     if (*OwnerId)
2703446Smrj     {
2713446Smrj         ACPI_ERROR ((AE_INFO, "Owner ID [%2.2X] already exists", *OwnerId));
2723446Smrj         return_ACPI_STATUS (AE_ALREADY_EXISTS);
2733446Smrj     }
2743446Smrj 
2753446Smrj     /* Mutex for the global ID mask */
2763446Smrj 
2773446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
2783446Smrj     if (ACPI_FAILURE (Status))
2793446Smrj     {
2803446Smrj         return_ACPI_STATUS (Status);
2813446Smrj     }
2823446Smrj 
2833446Smrj     /*
2843446Smrj      * Find a free owner ID, cycle through all possible IDs on repeated
2853446Smrj      * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
2863446Smrj      * to be scanned twice.
2873446Smrj      */
2883446Smrj     for (i = 0, j = AcpiGbl_LastOwnerIdIndex;
2893446Smrj          i < (ACPI_NUM_OWNERID_MASKS + 1);
2903446Smrj          i++, j++)
2913446Smrj     {
2923446Smrj         if (j >= ACPI_NUM_OWNERID_MASKS)
2933446Smrj         {
2943446Smrj             j = 0;  /* Wraparound to start of mask array */
2953446Smrj         }
2963446Smrj 
2973446Smrj         for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++)
2983446Smrj         {
2993446Smrj             if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX)
3003446Smrj             {
3013446Smrj                 /* There are no free IDs in this mask */
3023446Smrj 
3033446Smrj                 break;
3043446Smrj             }
3053446Smrj 
3063446Smrj             if (!(AcpiGbl_OwnerIdMask[j] & (1 << k)))
3073446Smrj             {
3083446Smrj                 /*
3093446Smrj                  * Found a free ID. The actual ID is the bit index plus one,
3103446Smrj                  * making zero an invalid Owner ID. Save this as the last ID
3113446Smrj                  * allocated and update the global ID mask.
3123446Smrj                  */
3133446Smrj                 AcpiGbl_OwnerIdMask[j] |= (1 << k);
3143446Smrj 
3153446Smrj                 AcpiGbl_LastOwnerIdIndex = (UINT8) j;
3163446Smrj                 AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1);
3173446Smrj 
3183446Smrj                 /*
3193446Smrj                  * Construct encoded ID from the index and bit position
3203446Smrj                  *
3213446Smrj                  * Note: Last [j].k (bit 255) is never used and is marked
3223446Smrj                  * permanently allocated (prevents +1 overflow)
3233446Smrj                  */
3243446Smrj                 *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j));
3253446Smrj 
3263446Smrj                 ACPI_DEBUG_PRINT ((ACPI_DB_VALUES,
3273446Smrj                     "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId));
3283446Smrj                 goto Exit;
3293446Smrj             }
3303446Smrj         }
3313446Smrj 
3323446Smrj         AcpiGbl_NextOwnerIdOffset = 0;
3333446Smrj     }
3343446Smrj 
3353446Smrj     /*
3363446Smrj      * All OwnerIds have been allocated. This typically should
3373446Smrj      * not happen since the IDs are reused after deallocation. The IDs are
3383446Smrj      * allocated upon table load (one per table) and method execution, and
3393446Smrj      * they are released when a table is unloaded or a method completes
3403446Smrj      * execution.
3413446Smrj      *
3423446Smrj      * If this error happens, there may be very deep nesting of invoked control
3433446Smrj      * methods, or there may be a bug where the IDs are not released.
3443446Smrj      */
3453446Smrj     Status = AE_OWNER_ID_LIMIT;
3463446Smrj     ACPI_ERROR ((AE_INFO,
3473446Smrj         "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
3483446Smrj 
3493446Smrj Exit:
3503446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
3513446Smrj     return_ACPI_STATUS (Status);
3523446Smrj }
3533446Smrj 
3543446Smrj 
3553446Smrj /*******************************************************************************
3563446Smrj  *
3573446Smrj  * FUNCTION:    AcpiUtReleaseOwnerId
3583446Smrj  *
3593446Smrj  * PARAMETERS:  OwnerIdPtr          - Pointer to a previously allocated OwnerID
3603446Smrj  *
3613446Smrj  * RETURN:      None. No error is returned because we are either exiting a
3623446Smrj  *              control method or unloading a table. Either way, we would
3633446Smrj  *              ignore any error anyway.
3643446Smrj  *
3653446Smrj  * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 255
3663446Smrj  *
3673446Smrj  ******************************************************************************/
3683446Smrj 
3693446Smrj void
3703446Smrj AcpiUtReleaseOwnerId (
3713446Smrj     ACPI_OWNER_ID           *OwnerIdPtr)
3723446Smrj {
3733446Smrj     ACPI_OWNER_ID           OwnerId = *OwnerIdPtr;
3743446Smrj     ACPI_STATUS             Status;
3757851SDana.Myers@Sun.COM     UINT32                  Index;
3763446Smrj     UINT32                  Bit;
3773446Smrj 
3783446Smrj 
3793446Smrj     ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId);
3803446Smrj 
3813446Smrj 
3823446Smrj     /* Always clear the input OwnerId (zero is an invalid ID) */
3833446Smrj 
3843446Smrj     *OwnerIdPtr = 0;
3853446Smrj 
3863446Smrj     /* Zero is not a valid OwnerID */
3873446Smrj 
3883446Smrj     if (OwnerId == 0)
3893446Smrj     {
3903446Smrj         ACPI_ERROR ((AE_INFO, "Invalid OwnerId: %2.2X", OwnerId));
3913446Smrj         return_VOID;
3923446Smrj     }
3933446Smrj 
3943446Smrj     /* Mutex for the global ID mask */
3953446Smrj 
3963446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
3973446Smrj     if (ACPI_FAILURE (Status))
3983446Smrj     {
3993446Smrj         return_VOID;
4003446Smrj     }
4013446Smrj 
4023446Smrj     /* Normalize the ID to zero */
4033446Smrj 
4043446Smrj     OwnerId--;
4053446Smrj 
4063446Smrj     /* Decode ID to index/offset pair */
4073446Smrj 
4083446Smrj     Index = ACPI_DIV_32 (OwnerId);
4093446Smrj     Bit = 1 << ACPI_MOD_32 (OwnerId);
4103446Smrj 
4113446Smrj     /* Free the owner ID only if it is valid */
4123446Smrj 
4133446Smrj     if (AcpiGbl_OwnerIdMask[Index] & Bit)
4143446Smrj     {
4153446Smrj         AcpiGbl_OwnerIdMask[Index] ^= Bit;
4163446Smrj     }
4173446Smrj     else
4183446Smrj     {
4193446Smrj         ACPI_ERROR ((AE_INFO,
4203446Smrj             "Release of non-allocated OwnerId: %2.2X", OwnerId + 1));
4213446Smrj     }
4223446Smrj 
4233446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
4243446Smrj     return_VOID;
4253446Smrj }
4263446Smrj 
4273446Smrj 
4283446Smrj /*******************************************************************************
4293446Smrj  *
4303446Smrj  * FUNCTION:    AcpiUtStrupr (strupr)
4313446Smrj  *
4323446Smrj  * PARAMETERS:  SrcString       - The source string to convert
4333446Smrj  *
4343446Smrj  * RETURN:      None
4353446Smrj  *
4363446Smrj  * DESCRIPTION: Convert string to uppercase
4373446Smrj  *
4383446Smrj  * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
4393446Smrj  *
4403446Smrj  ******************************************************************************/
4413446Smrj 
4423446Smrj void
4433446Smrj AcpiUtStrupr (
4443446Smrj     char                    *SrcString)
4453446Smrj {
4463446Smrj     char                    *String;
4473446Smrj 
4483446Smrj 
4493446Smrj     ACPI_FUNCTION_ENTRY ();
4503446Smrj 
4513446Smrj 
4523446Smrj     if (!SrcString)
4533446Smrj     {
4543446Smrj         return;
4553446Smrj     }
4563446Smrj 
4573446Smrj     /* Walk entire string, uppercasing the letters */
4583446Smrj 
4593446Smrj     for (String = SrcString; *String; String++)
4603446Smrj     {
4613446Smrj         *String = (char) ACPI_TOUPPER (*String);
4623446Smrj     }
4633446Smrj 
4643446Smrj     return;
4653446Smrj }
4663446Smrj 
4673446Smrj 
4683446Smrj /*******************************************************************************
4693446Smrj  *
4703446Smrj  * FUNCTION:    AcpiUtPrintString
4713446Smrj  *
4723446Smrj  * PARAMETERS:  String          - Null terminated ASCII string
4733446Smrj  *              MaxLength       - Maximum output length
4743446Smrj  *
4753446Smrj  * RETURN:      None
4763446Smrj  *
4773446Smrj  * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
4783446Smrj  *              sequences.
4793446Smrj  *
4803446Smrj  ******************************************************************************/
4813446Smrj 
4823446Smrj void
4833446Smrj AcpiUtPrintString (
4843446Smrj     char                    *String,
4853446Smrj     UINT8                   MaxLength)
4863446Smrj {
4873446Smrj     UINT32                  i;
4883446Smrj 
4893446Smrj 
4903446Smrj     if (!String)
4913446Smrj     {
4923446Smrj         AcpiOsPrintf ("<\"NULL STRING PTR\">");
4933446Smrj         return;
4943446Smrj     }
4953446Smrj 
4963446Smrj     AcpiOsPrintf ("\"");
4973446Smrj     for (i = 0; String[i] && (i < MaxLength); i++)
4983446Smrj     {
4993446Smrj         /* Escape sequences */
5003446Smrj 
5013446Smrj         switch (String[i])
5023446Smrj         {
5033446Smrj         case 0x07:
5043446Smrj             AcpiOsPrintf ("\\a");       /* BELL */
5053446Smrj             break;
5063446Smrj 
5073446Smrj         case 0x08:
5083446Smrj             AcpiOsPrintf ("\\b");       /* BACKSPACE */
5093446Smrj             break;
5103446Smrj 
5113446Smrj         case 0x0C:
5123446Smrj             AcpiOsPrintf ("\\f");       /* FORMFEED */
5133446Smrj             break;
5143446Smrj 
5153446Smrj         case 0x0A:
5163446Smrj             AcpiOsPrintf ("\\n");       /* LINEFEED */
5173446Smrj             break;
5183446Smrj 
5193446Smrj         case 0x0D:
5203446Smrj             AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
5213446Smrj             break;
5223446Smrj 
5233446Smrj         case 0x09:
5243446Smrj             AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
5253446Smrj             break;
5263446Smrj 
5273446Smrj         case 0x0B:
5283446Smrj             AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
5293446Smrj             break;
5303446Smrj 
5313446Smrj         case '\'':                      /* Single Quote */
5323446Smrj         case '\"':                      /* Double Quote */
5333446Smrj         case '\\':                      /* Backslash */
5343446Smrj             AcpiOsPrintf ("\\%c", (int) String[i]);
5353446Smrj             break;
5363446Smrj 
5373446Smrj         default:
5383446Smrj 
5393446Smrj             /* Check for printable character or hex escape */
5403446Smrj 
5413446Smrj             if (ACPI_IS_PRINT (String[i]))
5423446Smrj             {
5433446Smrj                 /* This is a normal character */
5443446Smrj 
5453446Smrj                 AcpiOsPrintf ("%c", (int) String[i]);
5463446Smrj             }
5473446Smrj             else
5483446Smrj             {
5493446Smrj                 /* All others will be Hex escapes */
5503446Smrj 
5513446Smrj                 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
5523446Smrj             }
5533446Smrj             break;
5543446Smrj         }
5553446Smrj     }
5563446Smrj     AcpiOsPrintf ("\"");
5573446Smrj 
5583446Smrj     if (i == MaxLength && String[i])
5593446Smrj     {
5603446Smrj         AcpiOsPrintf ("...");
5613446Smrj     }
5623446Smrj }
5633446Smrj 
5643446Smrj 
5653446Smrj /*******************************************************************************
5663446Smrj  *
5673446Smrj  * FUNCTION:    AcpiUtDwordByteSwap
5683446Smrj  *
5693446Smrj  * PARAMETERS:  Value           - Value to be converted
5703446Smrj  *
5713446Smrj  * RETURN:      UINT32 integer with bytes swapped
5723446Smrj  *
5733446Smrj  * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
5743446Smrj  *
5753446Smrj  ******************************************************************************/
5763446Smrj 
5773446Smrj UINT32
5783446Smrj AcpiUtDwordByteSwap (
5793446Smrj     UINT32                  Value)
5803446Smrj {
5813446Smrj     union
5823446Smrj     {
5833446Smrj         UINT32              Value;
5843446Smrj         UINT8               Bytes[4];
5853446Smrj     } Out;
5863446Smrj     union
5873446Smrj     {
5883446Smrj         UINT32              Value;
5893446Smrj         UINT8               Bytes[4];
5903446Smrj     } In;
5913446Smrj 
5923446Smrj 
5933446Smrj     ACPI_FUNCTION_ENTRY ();
5943446Smrj 
5953446Smrj 
5963446Smrj     In.Value = Value;
5973446Smrj 
5983446Smrj     Out.Bytes[0] = In.Bytes[3];
5993446Smrj     Out.Bytes[1] = In.Bytes[2];
6003446Smrj     Out.Bytes[2] = In.Bytes[1];
6013446Smrj     Out.Bytes[3] = In.Bytes[0];
6023446Smrj 
6033446Smrj     return (Out.Value);
6043446Smrj }
6053446Smrj 
6063446Smrj 
6073446Smrj /*******************************************************************************
6083446Smrj  *
6093446Smrj  * FUNCTION:    AcpiUtSetIntegerWidth
6103446Smrj  *
6113446Smrj  * PARAMETERS:  Revision            From DSDT header
6123446Smrj  *
6133446Smrj  * RETURN:      None
6143446Smrj  *
6153446Smrj  * DESCRIPTION: Set the global integer bit width based upon the revision
6163446Smrj  *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
6173446Smrj  *              For Revision 2 and above, Integers are 64 bits.  Yes, this
6183446Smrj  *              makes a difference.
6193446Smrj  *
6203446Smrj  ******************************************************************************/
6213446Smrj 
6223446Smrj void
6233446Smrj AcpiUtSetIntegerWidth (
6243446Smrj     UINT8                   Revision)
6253446Smrj {
6263446Smrj 
6277851SDana.Myers@Sun.COM     if (Revision < 2)
6283446Smrj     {
6293446Smrj         /* 32-bit case */
6303446Smrj 
6313446Smrj         AcpiGbl_IntegerBitWidth    = 32;
6323446Smrj         AcpiGbl_IntegerNybbleWidth = 8;
6333446Smrj         AcpiGbl_IntegerByteWidth   = 4;
6343446Smrj     }
6353446Smrj     else
6363446Smrj     {
6373446Smrj         /* 64-bit case (ACPI 2.0+) */
6383446Smrj 
6393446Smrj         AcpiGbl_IntegerBitWidth    = 64;
6403446Smrj         AcpiGbl_IntegerNybbleWidth = 16;
6413446Smrj         AcpiGbl_IntegerByteWidth   = 8;
6423446Smrj     }
6433446Smrj }
6443446Smrj 
6453446Smrj 
6463446Smrj #ifdef ACPI_DEBUG_OUTPUT
6473446Smrj /*******************************************************************************
6483446Smrj  *
6493446Smrj  * FUNCTION:    AcpiUtDisplayInitPathname
6503446Smrj  *
6513446Smrj  * PARAMETERS:  Type                - Object type of the node
6523446Smrj  *              ObjHandle           - Handle whose pathname will be displayed
6533446Smrj  *              Path                - Additional path string to be appended.
6543446Smrj  *                                      (NULL if no extra path)
6553446Smrj  *
6563446Smrj  * RETURN:      ACPI_STATUS
6573446Smrj  *
6583446Smrj  * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
6593446Smrj  *
6603446Smrj  ******************************************************************************/
6613446Smrj 
6623446Smrj void
6633446Smrj AcpiUtDisplayInitPathname (
6643446Smrj     UINT8                   Type,
6653446Smrj     ACPI_NAMESPACE_NODE     *ObjHandle,
6663446Smrj     char                    *Path)
6673446Smrj {
6683446Smrj     ACPI_STATUS             Status;
6693446Smrj     ACPI_BUFFER             Buffer;
6703446Smrj 
6713446Smrj 
6723446Smrj     ACPI_FUNCTION_ENTRY ();
6733446Smrj 
6743446Smrj 
6753446Smrj     /* Only print the path if the appropriate debug level is enabled */
6763446Smrj 
6773446Smrj     if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
6783446Smrj     {
6793446Smrj         return;
6803446Smrj     }
6813446Smrj 
6823446Smrj     /* Get the full pathname to the node */
6833446Smrj 
6843446Smrj     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
6853446Smrj     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
6863446Smrj     if (ACPI_FAILURE (Status))
6873446Smrj     {
6883446Smrj         return;
6893446Smrj     }
6903446Smrj 
6913446Smrj     /* Print what we're doing */
6923446Smrj 
6933446Smrj     switch (Type)
6943446Smrj     {
6953446Smrj     case ACPI_TYPE_METHOD:
6963446Smrj         AcpiOsPrintf ("Executing    ");
6973446Smrj         break;
6983446Smrj 
6993446Smrj     default:
7003446Smrj         AcpiOsPrintf ("Initializing ");
7013446Smrj         break;
7023446Smrj     }
7033446Smrj 
7043446Smrj     /* Print the object type and pathname */
7053446Smrj 
7063446Smrj     AcpiOsPrintf ("%-12s  %s",
7073446Smrj         AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
7083446Smrj 
7093446Smrj     /* Extra path is used to append names like _STA, _INI, etc. */
7103446Smrj 
7113446Smrj     if (Path)
7123446Smrj     {
7133446Smrj         AcpiOsPrintf (".%s", Path);
7143446Smrj     }
7153446Smrj     AcpiOsPrintf ("\n");
7163446Smrj 
7173446Smrj     ACPI_FREE (Buffer.Pointer);
7183446Smrj }
7193446Smrj #endif
7203446Smrj 
7213446Smrj 
7223446Smrj /*******************************************************************************
7233446Smrj  *
7243446Smrj  * FUNCTION:    AcpiUtValidAcpiChar
7253446Smrj  *
7263446Smrj  * PARAMETERS:  Char            - The character to be examined
7273446Smrj  *              Position        - Byte position (0-3)
7283446Smrj  *
7293446Smrj  * RETURN:      TRUE if the character is valid, FALSE otherwise
7303446Smrj  *
7313446Smrj  * DESCRIPTION: Check for a valid ACPI character. Must be one of:
7323446Smrj  *              1) Upper case alpha
7333446Smrj  *              2) numeric
7343446Smrj  *              3) underscore
7353446Smrj  *
7363446Smrj  *              We allow a '!' as the last character because of the ASF! table
7373446Smrj  *
7383446Smrj  ******************************************************************************/
7393446Smrj 
7403446Smrj BOOLEAN
7413446Smrj AcpiUtValidAcpiChar (
7423446Smrj     char                    Character,
7437851SDana.Myers@Sun.COM     UINT32                  Position)
7443446Smrj {
7453446Smrj 
7463446Smrj     if (!((Character >= 'A' && Character <= 'Z') ||
7473446Smrj           (Character >= '0' && Character <= '9') ||
7483446Smrj           (Character == '_')))
7493446Smrj     {
7503446Smrj         /* Allow a '!' in the last position */
7513446Smrj 
7523446Smrj         if (Character == '!' && Position == 3)
7533446Smrj         {
7543446Smrj             return (TRUE);
7553446Smrj         }
7563446Smrj 
7573446Smrj         return (FALSE);
7583446Smrj     }
7593446Smrj 
7603446Smrj     return (TRUE);
7613446Smrj }
7623446Smrj 
7633446Smrj 
7643446Smrj /*******************************************************************************
7653446Smrj  *
7663446Smrj  * FUNCTION:    AcpiUtValidAcpiName
7673446Smrj  *
7683446Smrj  * PARAMETERS:  Name            - The name to be examined
7693446Smrj  *
7703446Smrj  * RETURN:      TRUE if the name is valid, FALSE otherwise
7713446Smrj  *
7723446Smrj  * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
7733446Smrj  *              1) Upper case alpha
7743446Smrj  *              2) numeric
7753446Smrj  *              3) underscore
7763446Smrj  *
7773446Smrj  ******************************************************************************/
7783446Smrj 
7793446Smrj BOOLEAN
7803446Smrj AcpiUtValidAcpiName (
7813446Smrj     UINT32                  Name)
7823446Smrj {
7837851SDana.Myers@Sun.COM     UINT32                  i;
7843446Smrj 
7853446Smrj 
7863446Smrj     ACPI_FUNCTION_ENTRY ();
7873446Smrj 
7883446Smrj 
7893446Smrj     for (i = 0; i < ACPI_NAME_SIZE; i++)
7903446Smrj     {
7913446Smrj         if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i))
7923446Smrj         {
7933446Smrj             return (FALSE);
7943446Smrj         }
7953446Smrj     }
7963446Smrj 
7973446Smrj     return (TRUE);
7983446Smrj }
7993446Smrj 
8003446Smrj 
8013446Smrj /*******************************************************************************
8023446Smrj  *
8033446Smrj  * FUNCTION:    AcpiUtRepairName
8043446Smrj  *
8053446Smrj  * PARAMETERS:  Name            - The ACPI name to be repaired
8063446Smrj  *
8073446Smrj  * RETURN:      Repaired version of the name
8083446Smrj  *
8093446Smrj  * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
8107851SDana.Myers@Sun.COM  *              return the new name. NOTE: the Name parameter must reside in
8117851SDana.Myers@Sun.COM  *              read/write memory, cannot be a const.
8127851SDana.Myers@Sun.COM  *
8137851SDana.Myers@Sun.COM  * An ACPI Name must consist of valid ACPI characters. We will repair the name
8147851SDana.Myers@Sun.COM  * if necessary because we don't want to abort because of this, but we want
8157851SDana.Myers@Sun.COM  * all namespace names to be printable. A warning message is appropriate.
8167851SDana.Myers@Sun.COM  *
8177851SDana.Myers@Sun.COM  * This issue came up because there are in fact machines that exhibit
8187851SDana.Myers@Sun.COM  * this problem, and we want to be able to enable ACPI support for them,
8197851SDana.Myers@Sun.COM  * even though there are a few bad names.
8203446Smrj  *
8213446Smrj  ******************************************************************************/
8223446Smrj 
8237851SDana.Myers@Sun.COM void
8243446Smrj AcpiUtRepairName (
8257851SDana.Myers@Sun.COM     char                    *Name)
8263446Smrj {
8277851SDana.Myers@Sun.COM     UINT32                  i;
8287851SDana.Myers@Sun.COM     BOOLEAN                 FoundBadChar = FALSE;
8297851SDana.Myers@Sun.COM 
8303446Smrj 
8317851SDana.Myers@Sun.COM     ACPI_FUNCTION_NAME (UtRepairName);
8327851SDana.Myers@Sun.COM 
8337851SDana.Myers@Sun.COM 
8347851SDana.Myers@Sun.COM     /* Check each character in the name */
8353446Smrj 
8363446Smrj     for (i = 0; i < ACPI_NAME_SIZE; i++)
8373446Smrj     {
8387851SDana.Myers@Sun.COM         if (AcpiUtValidAcpiChar (Name[i], i))
8397851SDana.Myers@Sun.COM         {
8407851SDana.Myers@Sun.COM             continue;
8417851SDana.Myers@Sun.COM         }
8423446Smrj 
8433446Smrj         /*
8443446Smrj          * Replace a bad character with something printable, yet technically
8453446Smrj          * still invalid. This prevents any collisions with existing "good"
8463446Smrj          * names in the namespace.
8473446Smrj          */
8487851SDana.Myers@Sun.COM         Name[i] = '*';
8497851SDana.Myers@Sun.COM         FoundBadChar = TRUE;
8507851SDana.Myers@Sun.COM     }
8517851SDana.Myers@Sun.COM 
8527851SDana.Myers@Sun.COM     if (FoundBadChar)
8537851SDana.Myers@Sun.COM     {
8547851SDana.Myers@Sun.COM         /* Report warning only if in strict mode or debug mode */
8557851SDana.Myers@Sun.COM 
8567851SDana.Myers@Sun.COM         if (!AcpiGbl_EnableInterpreterSlack)
8573446Smrj         {
8587851SDana.Myers@Sun.COM             ACPI_WARNING ((AE_INFO,
8597851SDana.Myers@Sun.COM                 "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
8607851SDana.Myers@Sun.COM         }
8617851SDana.Myers@Sun.COM         else
8627851SDana.Myers@Sun.COM         {
8637851SDana.Myers@Sun.COM             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
8647851SDana.Myers@Sun.COM                 "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
8653446Smrj         }
8663446Smrj     }
8673446Smrj }
8683446Smrj 
8693446Smrj 
8703446Smrj /*******************************************************************************
8713446Smrj  *
8723446Smrj  * FUNCTION:    AcpiUtStrtoul64
8733446Smrj  *
8743446Smrj  * PARAMETERS:  String          - Null terminated string
8753446Smrj  *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
8763446Smrj  *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
8773446Smrj  *              RetInteger      - Where the converted integer is returned
8783446Smrj  *
8793446Smrj  * RETURN:      Status and Converted value
8803446Smrj  *
8813446Smrj  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
8823446Smrj  *              32-bit or 64-bit conversion, depending on the current mode
8833446Smrj  *              of the interpreter.
8843446Smrj  *              NOTE: Does not support Octal strings, not needed.
8853446Smrj  *
8863446Smrj  ******************************************************************************/
8873446Smrj 
8883446Smrj ACPI_STATUS
8893446Smrj AcpiUtStrtoul64 (
8903446Smrj     char                    *String,
8913446Smrj     UINT32                  Base,
8923446Smrj     ACPI_INTEGER            *RetInteger)
8933446Smrj {
8943446Smrj     UINT32                  ThisDigit = 0;
8953446Smrj     ACPI_INTEGER            ReturnValue = 0;
8963446Smrj     ACPI_INTEGER            Quotient;
8973446Smrj     ACPI_INTEGER            Dividend;
8983446Smrj     UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
8993446Smrj     UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
9003446Smrj     UINT8                   ValidDigits = 0;
9013446Smrj     UINT8                   SignOf0x = 0;
9023446Smrj     UINT8                   Term = 0;
9033446Smrj 
9043446Smrj 
9053446Smrj     ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
9063446Smrj 
9073446Smrj 
9083446Smrj     switch (Base)
9093446Smrj     {
9103446Smrj     case ACPI_ANY_BASE:
9113446Smrj     case 16:
9123446Smrj         break;
9133446Smrj 
9143446Smrj     default:
9153446Smrj         /* Invalid Base */
9163446Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
9173446Smrj     }
9183446Smrj 
9193446Smrj     if (!String)
9203446Smrj     {
9213446Smrj         goto ErrorExit;
9223446Smrj     }
9233446Smrj 
9243446Smrj     /* Skip over any white space in the buffer */
9253446Smrj 
9263446Smrj     while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
9273446Smrj     {
9283446Smrj         String++;
9293446Smrj     }
9303446Smrj 
9313446Smrj     if (ToIntegerOp)
9323446Smrj     {
9333446Smrj         /*
9343446Smrj          * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
9353446Smrj          * We need to determine if it is decimal or hexadecimal.
9363446Smrj          */
9373446Smrj         if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
9383446Smrj         {
9393446Smrj             SignOf0x = 1;
9403446Smrj             Base = 16;
9413446Smrj 
9423446Smrj             /* Skip over the leading '0x' */
9433446Smrj             String += 2;
9443446Smrj         }
9453446Smrj         else
9463446Smrj         {
9473446Smrj             Base = 10;
9483446Smrj         }
9493446Smrj     }
9503446Smrj 
9513446Smrj     /* Any string left? Check that '0x' is not followed by white space. */
9523446Smrj 
9533446Smrj     if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
9543446Smrj     {
9553446Smrj         if (ToIntegerOp)
9563446Smrj         {
9573446Smrj             goto ErrorExit;
9583446Smrj         }
9593446Smrj         else
9603446Smrj         {
9613446Smrj             goto AllDone;
9623446Smrj         }
9633446Smrj     }
9643446Smrj 
9653446Smrj     /*
9663446Smrj      * Perform a 32-bit or 64-bit conversion, depending upon the current
9673446Smrj      * execution mode of the interpreter
9683446Smrj      */
9693446Smrj     Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
9703446Smrj 
9713446Smrj     /* Main loop: convert the string to a 32- or 64-bit integer */
9723446Smrj 
9733446Smrj     while (*String)
9743446Smrj     {
9753446Smrj         if (ACPI_IS_DIGIT (*String))
9763446Smrj         {
9773446Smrj             /* Convert ASCII 0-9 to Decimal value */
9783446Smrj 
9793446Smrj             ThisDigit = ((UINT8) *String) - '0';
9803446Smrj         }
9813446Smrj         else if (Base == 10)
9823446Smrj         {
9833446Smrj             /* Digit is out of range; possible in ToInteger case only */
9843446Smrj 
9853446Smrj             Term = 1;
9863446Smrj         }
9873446Smrj         else
9883446Smrj         {
9893446Smrj             ThisDigit = (UINT8) ACPI_TOUPPER (*String);
9903446Smrj             if (ACPI_IS_XDIGIT ((char) ThisDigit))
9913446Smrj             {
9923446Smrj                 /* Convert ASCII Hex char to value */
9933446Smrj 
9943446Smrj                 ThisDigit = ThisDigit - 'A' + 10;
9953446Smrj             }
9963446Smrj             else
9973446Smrj             {
9983446Smrj                 Term = 1;
9993446Smrj             }
10003446Smrj         }
10013446Smrj 
10023446Smrj         if (Term)
10033446Smrj         {
10043446Smrj             if (ToIntegerOp)
10053446Smrj             {
10063446Smrj                 goto ErrorExit;
10073446Smrj             }
10083446Smrj             else
10093446Smrj             {
10103446Smrj                 break;
10113446Smrj             }
10123446Smrj         }
10133446Smrj         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
10143446Smrj         {
10153446Smrj             /* Skip zeros */
10163446Smrj             String++;
10173446Smrj             continue;
10183446Smrj         }
10193446Smrj 
10203446Smrj         ValidDigits++;
10213446Smrj 
10223446Smrj         if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
10233446Smrj         {
10243446Smrj             /*
10253446Smrj              * This is ToInteger operation case.
10263446Smrj              * No any restrictions for string-to-integer conversion,
10273446Smrj              * see ACPI spec.
10283446Smrj              */
10293446Smrj             goto ErrorExit;
10303446Smrj         }
10313446Smrj 
10323446Smrj         /* Divide the digit into the correct position */
10333446Smrj 
10343446Smrj         (void) AcpiUtShortDivide ((Dividend - (ACPI_INTEGER) ThisDigit),
10353446Smrj                     Base, &Quotient, NULL);
10363446Smrj 
10373446Smrj         if (ReturnValue > Quotient)
10383446Smrj         {
10393446Smrj             if (ToIntegerOp)
10403446Smrj             {
10413446Smrj                 goto ErrorExit;
10423446Smrj             }
10433446Smrj             else
10443446Smrj             {
10453446Smrj                 break;
10463446Smrj             }
10473446Smrj         }
10483446Smrj 
10493446Smrj         ReturnValue *= Base;
10503446Smrj         ReturnValue += ThisDigit;
10513446Smrj         String++;
10523446Smrj     }
10533446Smrj 
10543446Smrj     /* All done, normal exit */
10553446Smrj 
10563446Smrj AllDone:
10573446Smrj 
10583446Smrj     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
10593446Smrj         ACPI_FORMAT_UINT64 (ReturnValue)));
10603446Smrj 
10613446Smrj     *RetInteger = ReturnValue;
10623446Smrj     return_ACPI_STATUS (AE_OK);
10633446Smrj 
10643446Smrj 
10653446Smrj ErrorExit:
10663446Smrj     /* Base was set/validated above */
10673446Smrj 
10683446Smrj     if (Base == 10)
10693446Smrj     {
10703446Smrj         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
10713446Smrj     }
10723446Smrj     else
10733446Smrj     {
10743446Smrj         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
10753446Smrj     }
10763446Smrj }
10773446Smrj 
10783446Smrj 
10793446Smrj /*******************************************************************************
10803446Smrj  *
10813446Smrj  * FUNCTION:    AcpiUtCreateUpdateStateAndPush
10823446Smrj  *
10833446Smrj  * PARAMETERS:  Object          - Object to be added to the new state
10843446Smrj  *              Action          - Increment/Decrement
10853446Smrj  *              StateList       - List the state will be added to
10863446Smrj  *
10873446Smrj  * RETURN:      Status
10883446Smrj  *
10893446Smrj  * DESCRIPTION: Create a new state and push it
10903446Smrj  *
10913446Smrj  ******************************************************************************/
10923446Smrj 
10933446Smrj ACPI_STATUS
10943446Smrj AcpiUtCreateUpdateStateAndPush (
10953446Smrj     ACPI_OPERAND_OBJECT     *Object,
10963446Smrj     UINT16                  Action,
10973446Smrj     ACPI_GENERIC_STATE      **StateList)
10983446Smrj {
10993446Smrj     ACPI_GENERIC_STATE       *State;
11003446Smrj 
11013446Smrj 
11023446Smrj     ACPI_FUNCTION_ENTRY ();
11033446Smrj 
11043446Smrj 
11053446Smrj     /* Ignore null objects; these are expected */
11063446Smrj 
11073446Smrj     if (!Object)
11083446Smrj     {
11093446Smrj         return (AE_OK);
11103446Smrj     }
11113446Smrj 
11123446Smrj     State = AcpiUtCreateUpdateState (Object, Action);
11133446Smrj     if (!State)
11143446Smrj     {
11153446Smrj         return (AE_NO_MEMORY);
11163446Smrj     }
11173446Smrj 
11183446Smrj     AcpiUtPushGenericState (StateList, State);
11193446Smrj     return (AE_OK);
11203446Smrj }
11213446Smrj 
11223446Smrj 
11233446Smrj /*******************************************************************************
11243446Smrj  *
11253446Smrj  * FUNCTION:    AcpiUtWalkPackageTree
11263446Smrj  *
11273446Smrj  * PARAMETERS:  SourceObject        - The package to walk
11283446Smrj  *              TargetObject        - Target object (if package is being copied)
11293446Smrj  *              WalkCallback        - Called once for each package element
11303446Smrj  *              Context             - Passed to the callback function
11313446Smrj  *
11323446Smrj  * RETURN:      Status
11333446Smrj  *
11343446Smrj  * DESCRIPTION: Walk through a package
11353446Smrj  *
11363446Smrj  ******************************************************************************/
11373446Smrj 
11383446Smrj ACPI_STATUS
11393446Smrj AcpiUtWalkPackageTree (
11403446Smrj     ACPI_OPERAND_OBJECT     *SourceObject,
11413446Smrj     void                    *TargetObject,
11423446Smrj     ACPI_PKG_CALLBACK       WalkCallback,
11433446Smrj     void                    *Context)
11443446Smrj {
11453446Smrj     ACPI_STATUS             Status = AE_OK;
11463446Smrj     ACPI_GENERIC_STATE      *StateList = NULL;
11473446Smrj     ACPI_GENERIC_STATE      *State;
11483446Smrj     UINT32                  ThisIndex;
11493446Smrj     ACPI_OPERAND_OBJECT     *ThisSourceObj;
11503446Smrj 
11513446Smrj 
11523446Smrj     ACPI_FUNCTION_TRACE (UtWalkPackageTree);
11533446Smrj 
11543446Smrj 
11553446Smrj     State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
11563446Smrj     if (!State)
11573446Smrj     {
11583446Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
11593446Smrj     }
11603446Smrj 
11613446Smrj     while (State)
11623446Smrj     {
11633446Smrj         /* Get one element of the package */
11643446Smrj 
11653446Smrj         ThisIndex     = State->Pkg.Index;
11663446Smrj         ThisSourceObj = (ACPI_OPERAND_OBJECT *)
11673446Smrj                         State->Pkg.SourceObject->Package.Elements[ThisIndex];
11683446Smrj 
11693446Smrj         /*
11703446Smrj          * Check for:
11713446Smrj          * 1) An uninitialized package element.  It is completely
11723446Smrj          *    legal to declare a package and leave it uninitialized
11733446Smrj          * 2) Not an internal object - can be a namespace node instead
11743446Smrj          * 3) Any type other than a package.  Packages are handled in else
11753446Smrj          *    case below.
11763446Smrj          */
11773446Smrj         if ((!ThisSourceObj) ||
11783446Smrj             (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
1179*9980SDana.Myers@Sun.COM             (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
11803446Smrj         {
11813446Smrj             Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
11823446Smrj                                     State, Context);
11833446Smrj             if (ACPI_FAILURE (Status))
11843446Smrj             {
11853446Smrj                 return_ACPI_STATUS (Status);
11863446Smrj             }
11873446Smrj 
11883446Smrj             State->Pkg.Index++;
11893446Smrj             while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
11903446Smrj             {
11913446Smrj                 /*
11923446Smrj                  * We've handled all of the objects at this level,  This means
11933446Smrj                  * that we have just completed a package.  That package may
11943446Smrj                  * have contained one or more packages itself.
11953446Smrj                  *
11963446Smrj                  * Delete this state and pop the previous state (package).
11973446Smrj                  */
11983446Smrj                 AcpiUtDeleteGenericState (State);
11993446Smrj                 State = AcpiUtPopGenericState (&StateList);
12003446Smrj 
12013446Smrj                 /* Finished when there are no more states */
12023446Smrj 
12033446Smrj                 if (!State)
12043446Smrj                 {
12053446Smrj                     /*
12063446Smrj                      * We have handled all of the objects in the top level
12073446Smrj                      * package just add the length of the package objects
12083446Smrj                      * and exit
12093446Smrj                      */
12103446Smrj                     return_ACPI_STATUS (AE_OK);
12113446Smrj                 }
12123446Smrj 
12133446Smrj                 /*
12143446Smrj                  * Go back up a level and move the index past the just
12153446Smrj                  * completed package object.
12163446Smrj                  */
12173446Smrj                 State->Pkg.Index++;
12183446Smrj             }
12193446Smrj         }
12203446Smrj         else
12213446Smrj         {
12223446Smrj             /* This is a subobject of type package */
12233446Smrj 
12243446Smrj             Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
12253446Smrj                                         State, Context);
12263446Smrj             if (ACPI_FAILURE (Status))
12273446Smrj             {
12283446Smrj                 return_ACPI_STATUS (Status);
12293446Smrj             }
12303446Smrj 
12313446Smrj             /*
12323446Smrj              * Push the current state and create a new one
12333446Smrj              * The callback above returned a new target package object.
12343446Smrj              */
12353446Smrj             AcpiUtPushGenericState (&StateList, State);
12363446Smrj             State = AcpiUtCreatePkgState (ThisSourceObj,
12373446Smrj                                             State->Pkg.ThisTargetObj, 0);
12383446Smrj             if (!State)
12393446Smrj             {
1240*9980SDana.Myers@Sun.COM                 /* Free any stacked Update State objects */
1241*9980SDana.Myers@Sun.COM 
1242*9980SDana.Myers@Sun.COM                 while (StateList)
1243*9980SDana.Myers@Sun.COM                 {
1244*9980SDana.Myers@Sun.COM                     State = AcpiUtPopGenericState (&StateList);
1245*9980SDana.Myers@Sun.COM                     AcpiUtDeleteGenericState (State);
1246*9980SDana.Myers@Sun.COM                 }
12473446Smrj                 return_ACPI_STATUS (AE_NO_MEMORY);
12483446Smrj             }
12493446Smrj         }
12503446Smrj     }
12513446Smrj 
12523446Smrj     /* We should never get here */
12533446Smrj 
12543446Smrj     return_ACPI_STATUS (AE_AML_INTERNAL);
12553446Smrj }
12563446Smrj 
12573446Smrj 
12583446Smrj /*******************************************************************************
12593446Smrj  *
1260*9980SDana.Myers@Sun.COM  * FUNCTION:    AcpiError, AcpiException, AcpiWarning, AcpiInfo
12613446Smrj  *
12623446Smrj  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
12633446Smrj  *              LineNumber          - Caller's line number (for error output)
12643446Smrj  *              Format              - Printf format string + additional args
12653446Smrj  *
12663446Smrj  * RETURN:      None
12673446Smrj  *
12683446Smrj  * DESCRIPTION: Print message with module/line/version info
12693446Smrj  *
12703446Smrj  ******************************************************************************/
12713446Smrj 
12723446Smrj void  ACPI_INTERNAL_VAR_XFACE
1273*9980SDana.Myers@Sun.COM AcpiError (
12747851SDana.Myers@Sun.COM     const char              *ModuleName,
12753446Smrj     UINT32                  LineNumber,
12767851SDana.Myers@Sun.COM     const char              *Format,
12773446Smrj     ...)
12783446Smrj {
12793446Smrj     va_list                 args;
12803446Smrj 
12813446Smrj 
1282*9980SDana.Myers@Sun.COM     AcpiOsPrintf ("ACPI Error: ");
12833446Smrj 
12843446Smrj     va_start (args, Format);
12853446Smrj     AcpiOsVprintf (Format, args);
1286*9980SDana.Myers@Sun.COM     AcpiOsPrintf (" %8.8X %s-%u\n", ACPI_CA_VERSION, ModuleName, LineNumber);
12877851SDana.Myers@Sun.COM     va_end (args);
12883446Smrj }
12893446Smrj 
12903446Smrj void  ACPI_INTERNAL_VAR_XFACE
1291*9980SDana.Myers@Sun.COM AcpiException (
12927851SDana.Myers@Sun.COM     const char              *ModuleName,
12933446Smrj     UINT32                  LineNumber,
12943446Smrj     ACPI_STATUS             Status,
12957851SDana.Myers@Sun.COM     const char              *Format,
12963446Smrj     ...)
12973446Smrj {
12983446Smrj     va_list                 args;
12993446Smrj 
13003446Smrj 
1301*9980SDana.Myers@Sun.COM     AcpiOsPrintf ("ACPI Exception: %s, ", AcpiFormatException (Status));
13023446Smrj 
13033446Smrj     va_start (args, Format);
13043446Smrj     AcpiOsVprintf (Format, args);
1305*9980SDana.Myers@Sun.COM     AcpiOsPrintf (" %8.8X %s-%u\n", ACPI_CA_VERSION, ModuleName, LineNumber);
13067851SDana.Myers@Sun.COM     va_end (args);
13073446Smrj }
13083446Smrj 
13093446Smrj void  ACPI_INTERNAL_VAR_XFACE
1310*9980SDana.Myers@Sun.COM AcpiWarning (
13117851SDana.Myers@Sun.COM     const char              *ModuleName,
13123446Smrj     UINT32                  LineNumber,
13137851SDana.Myers@Sun.COM     const char              *Format,
13143446Smrj     ...)
13153446Smrj {
13163446Smrj     va_list                 args;
13173446Smrj 
13183446Smrj 
1319*9980SDana.Myers@Sun.COM     AcpiOsPrintf ("ACPI Warning: ");
13203446Smrj 
13213446Smrj     va_start (args, Format);
13223446Smrj     AcpiOsVprintf (Format, args);
1323*9980SDana.Myers@Sun.COM     AcpiOsPrintf (" %8.8X %s-%u\n", ACPI_CA_VERSION, ModuleName, LineNumber);
13247851SDana.Myers@Sun.COM     va_end (args);
13253446Smrj }
13263446Smrj 
13273446Smrj void  ACPI_INTERNAL_VAR_XFACE
1328*9980SDana.Myers@Sun.COM AcpiInfo (
13297851SDana.Myers@Sun.COM     const char              *ModuleName,
13303446Smrj     UINT32                  LineNumber,
13317851SDana.Myers@Sun.COM     const char              *Format,
13323446Smrj     ...)
13333446Smrj {
13343446Smrj     va_list                 args;
13353446Smrj 
13363446Smrj 
13377851SDana.Myers@Sun.COM     AcpiOsPrintf ("ACPI: ");
13383446Smrj 
13393446Smrj     va_start (args, Format);
13403446Smrj     AcpiOsVprintf (Format, args);
13417851SDana.Myers@Sun.COM     AcpiOsPrintf ("\n");
13427851SDana.Myers@Sun.COM     va_end (args);
13433446Smrj }
13443446Smrj 
1345*9980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiError)
1346*9980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiException)
1347*9980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiWarning)
1348*9980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiInfo)
1349*9980SDana.Myers@Sun.COM 
1350*9980SDana.Myers@Sun.COM 
1351