13446Smrj /*******************************************************************************
23446Smrj  *
33446Smrj  * Module Name: utmisc - common utility procedures
4*7851SDana.Myers@Sun.COM  *              $Revision: 1.154 $
53446Smrj  *
63446Smrj  ******************************************************************************/
73446Smrj 
83446Smrj /******************************************************************************
93446Smrj  *
103446Smrj  * 1. Copyright Notice
113446Smrj  *
12*7851SDana.Myers@Sun.COM  * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp.
133446Smrj  * All rights reserved.
143446Smrj  *
153446Smrj  * 2. License
163446Smrj  *
173446Smrj  * 2.1. This is your license from Intel Corp. under its intellectual property
183446Smrj  * rights.  You may have additional license terms from the party that provided
193446Smrj  * you this software, covering your right to use that party's intellectual
203446Smrj  * property rights.
213446Smrj  *
223446Smrj  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
233446Smrj  * copy of the source code appearing in this file ("Covered Code") an
243446Smrj  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
253446Smrj  * base code distributed originally by Intel ("Original Intel Code") to copy,
263446Smrj  * make derivatives, distribute, use and display any portion of the Covered
273446Smrj  * Code in any form, with the right to sublicense such rights; and
283446Smrj  *
293446Smrj  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
303446Smrj  * license (with the right to sublicense), under only those claims of Intel
313446Smrj  * patents that are infringed by the Original Intel Code, to make, use, sell,
323446Smrj  * offer to sell, and import the Covered Code and derivative works thereof
333446Smrj  * solely to the minimum extent necessary to exercise the above copyright
343446Smrj  * license, and in no event shall the patent license extend to any additions
353446Smrj  * to or modifications of the Original Intel Code.  No other license or right
363446Smrj  * is granted directly or by implication, estoppel or otherwise;
373446Smrj  *
383446Smrj  * The above copyright and patent license is granted only if the following
393446Smrj  * conditions are met:
403446Smrj  *
413446Smrj  * 3. Conditions
423446Smrj  *
433446Smrj  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
443446Smrj  * Redistribution of source code of any substantial portion of the Covered
453446Smrj  * Code or modification with rights to further distribute source must include
463446Smrj  * the above Copyright Notice, the above License, this list of Conditions,
473446Smrj  * and the following Disclaimer and Export Compliance provision.  In addition,
483446Smrj  * Licensee must cause all Covered Code to which Licensee contributes to
493446Smrj  * contain a file documenting the changes Licensee made to create that Covered
503446Smrj  * Code and the date of any change.  Licensee must include in that file the
513446Smrj  * documentation of any changes made by any predecessor Licensee.  Licensee
523446Smrj  * must include a prominent statement that the modification is derived,
533446Smrj  * directly or indirectly, from Original Intel Code.
543446Smrj  *
553446Smrj  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
563446Smrj  * Redistribution of source code of any substantial portion of the Covered
573446Smrj  * Code or modification without rights to further distribute source must
583446Smrj  * include the following Disclaimer and Export Compliance provision in the
593446Smrj  * documentation and/or other materials provided with distribution.  In
603446Smrj  * addition, Licensee may not authorize further sublicense of source of any
613446Smrj  * portion of the Covered Code, and must include terms to the effect that the
623446Smrj  * license from Licensee to its licensee is limited to the intellectual
633446Smrj  * property embodied in the software Licensee provides to its licensee, and
643446Smrj  * not to intellectual property embodied in modifications its licensee may
653446Smrj  * make.
663446Smrj  *
673446Smrj  * 3.3. Redistribution of Executable. Redistribution in executable form of any
683446Smrj  * substantial portion of the Covered Code or modification must reproduce the
693446Smrj  * above Copyright Notice, and the following Disclaimer and Export Compliance
703446Smrj  * provision in the documentation and/or other materials provided with the
713446Smrj  * distribution.
723446Smrj  *
733446Smrj  * 3.4. Intel retains all right, title, and interest in and to the Original
743446Smrj  * Intel Code.
753446Smrj  *
763446Smrj  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
773446Smrj  * Intel shall be used in advertising or otherwise to promote the sale, use or
783446Smrj  * other dealings in products derived from or relating to the Covered Code
793446Smrj  * without prior written authorization from Intel.
803446Smrj  *
813446Smrj  * 4. Disclaimer and Export Compliance
823446Smrj  *
833446Smrj  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
843446Smrj  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
853446Smrj  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
863446Smrj  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
873446Smrj  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
883446Smrj  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
893446Smrj  * PARTICULAR PURPOSE.
903446Smrj  *
913446Smrj  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
923446Smrj  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
933446Smrj  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
943446Smrj  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
953446Smrj  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
963446Smrj  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
973446Smrj  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
983446Smrj  * LIMITED REMEDY.
993446Smrj  *
1003446Smrj  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1013446Smrj  * software or system incorporating such software without first obtaining any
1023446Smrj  * required license or other approval from the U. S. Department of Commerce or
1033446Smrj  * any other agency or department of the United States Government.  In the
1043446Smrj  * event Licensee exports any such software from the United States or
1053446Smrj  * re-exports any such software from a foreign destination, Licensee shall
1063446Smrj  * ensure that the distribution and export/re-export of the software is in
1073446Smrj  * compliance with all laws, regulations, orders, or other restrictions of the
1083446Smrj  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1093446Smrj  * any of its subsidiaries will export/re-export any technical data, process,
1103446Smrj  * software, or service, directly or indirectly, to any country for which the
1113446Smrj  * United States government or any agency thereof requires an export license,
1123446Smrj  * other governmental approval, or letter of assurance, without first obtaining
1133446Smrj  * such license, approval or letter.
1143446Smrj  *
1153446Smrj  *****************************************************************************/
1163446Smrj 
1173446Smrj 
1183446Smrj #define __UTMISC_C__
1193446Smrj 
1203446Smrj #include "acpi.h"
1213446Smrj #include "acnamesp.h"
1223446Smrj 
1233446Smrj 
1243446Smrj #define _COMPONENT          ACPI_UTILITIES
1253446Smrj         ACPI_MODULE_NAME    ("utmisc")
1263446Smrj 
1273446Smrj 
1283446Smrj /*******************************************************************************
1293446Smrj  *
130*7851SDana.Myers@Sun.COM  * FUNCTION:    AcpiUtValidateException
131*7851SDana.Myers@Sun.COM  *
132*7851SDana.Myers@Sun.COM  * PARAMETERS:  Status       - The ACPI_STATUS code to be formatted
133*7851SDana.Myers@Sun.COM  *
134*7851SDana.Myers@Sun.COM  * RETURN:      A string containing the exception text. NULL if exception is
135*7851SDana.Myers@Sun.COM  *              not valid.
136*7851SDana.Myers@Sun.COM  *
137*7851SDana.Myers@Sun.COM  * DESCRIPTION: This function validates and translates an ACPI exception into
138*7851SDana.Myers@Sun.COM  *              an ASCII string.
139*7851SDana.Myers@Sun.COM  *
140*7851SDana.Myers@Sun.COM  ******************************************************************************/
141*7851SDana.Myers@Sun.COM 
142*7851SDana.Myers@Sun.COM const char *
143*7851SDana.Myers@Sun.COM AcpiUtValidateException (
144*7851SDana.Myers@Sun.COM     ACPI_STATUS             Status)
145*7851SDana.Myers@Sun.COM {
146*7851SDana.Myers@Sun.COM     UINT32                  SubStatus;
147*7851SDana.Myers@Sun.COM     const char              *Exception = NULL;
148*7851SDana.Myers@Sun.COM 
149*7851SDana.Myers@Sun.COM 
150*7851SDana.Myers@Sun.COM     ACPI_FUNCTION_ENTRY ();
151*7851SDana.Myers@Sun.COM 
152*7851SDana.Myers@Sun.COM 
153*7851SDana.Myers@Sun.COM     /*
154*7851SDana.Myers@Sun.COM      * Status is composed of two parts, a "type" and an actual code
155*7851SDana.Myers@Sun.COM      */
156*7851SDana.Myers@Sun.COM     SubStatus = (Status & ~AE_CODE_MASK);
157*7851SDana.Myers@Sun.COM 
158*7851SDana.Myers@Sun.COM     switch (Status & AE_CODE_MASK)
159*7851SDana.Myers@Sun.COM     {
160*7851SDana.Myers@Sun.COM     case AE_CODE_ENVIRONMENTAL:
161*7851SDana.Myers@Sun.COM 
162*7851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_ENV_MAX)
163*7851SDana.Myers@Sun.COM         {
164*7851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
165*7851SDana.Myers@Sun.COM         }
166*7851SDana.Myers@Sun.COM         break;
167*7851SDana.Myers@Sun.COM 
168*7851SDana.Myers@Sun.COM     case AE_CODE_PROGRAMMER:
169*7851SDana.Myers@Sun.COM 
170*7851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_PGM_MAX)
171*7851SDana.Myers@Sun.COM         {
172*7851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
173*7851SDana.Myers@Sun.COM         }
174*7851SDana.Myers@Sun.COM         break;
175*7851SDana.Myers@Sun.COM 
176*7851SDana.Myers@Sun.COM     case AE_CODE_ACPI_TABLES:
177*7851SDana.Myers@Sun.COM 
178*7851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_TBL_MAX)
179*7851SDana.Myers@Sun.COM         {
180*7851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
181*7851SDana.Myers@Sun.COM         }
182*7851SDana.Myers@Sun.COM         break;
183*7851SDana.Myers@Sun.COM 
184*7851SDana.Myers@Sun.COM     case AE_CODE_AML:
185*7851SDana.Myers@Sun.COM 
186*7851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_AML_MAX)
187*7851SDana.Myers@Sun.COM         {
188*7851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
189*7851SDana.Myers@Sun.COM         }
190*7851SDana.Myers@Sun.COM         break;
191*7851SDana.Myers@Sun.COM 
192*7851SDana.Myers@Sun.COM     case AE_CODE_CONTROL:
193*7851SDana.Myers@Sun.COM 
194*7851SDana.Myers@Sun.COM         if (SubStatus <= AE_CODE_CTRL_MAX)
195*7851SDana.Myers@Sun.COM         {
196*7851SDana.Myers@Sun.COM             Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
197*7851SDana.Myers@Sun.COM         }
198*7851SDana.Myers@Sun.COM         break;
199*7851SDana.Myers@Sun.COM 
200*7851SDana.Myers@Sun.COM     default:
201*7851SDana.Myers@Sun.COM         break;
202*7851SDana.Myers@Sun.COM     }
203*7851SDana.Myers@Sun.COM 
204*7851SDana.Myers@Sun.COM     return (ACPI_CAST_PTR (const char, Exception));
205*7851SDana.Myers@Sun.COM }
206*7851SDana.Myers@Sun.COM 
207*7851SDana.Myers@Sun.COM 
208*7851SDana.Myers@Sun.COM /*******************************************************************************
209*7851SDana.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 
229*7851SDana.Myers@Sun.COM     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
230*7851SDana.Myers@Sun.COM         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
231*7851SDana.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 {
258*7851SDana.Myers@Sun.COM     UINT32                  i;
259*7851SDana.Myers@Sun.COM     UINT32                  j;
260*7851SDana.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;
375*7851SDana.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 
627*7851SDana.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,
743*7851SDana.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 {
783*7851SDana.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
810*7851SDana.Myers@Sun.COM  *              return the new name. NOTE: the Name parameter must reside in
811*7851SDana.Myers@Sun.COM  *              read/write memory, cannot be a const.
812*7851SDana.Myers@Sun.COM  *
813*7851SDana.Myers@Sun.COM  * An ACPI Name must consist of valid ACPI characters. We will repair the name
814*7851SDana.Myers@Sun.COM  * if necessary because we don't want to abort because of this, but we want
815*7851SDana.Myers@Sun.COM  * all namespace names to be printable. A warning message is appropriate.
816*7851SDana.Myers@Sun.COM  *
817*7851SDana.Myers@Sun.COM  * This issue came up because there are in fact machines that exhibit
818*7851SDana.Myers@Sun.COM  * this problem, and we want to be able to enable ACPI support for them,
819*7851SDana.Myers@Sun.COM  * even though there are a few bad names.
8203446Smrj  *
8213446Smrj  ******************************************************************************/
8223446Smrj 
823*7851SDana.Myers@Sun.COM void
8243446Smrj AcpiUtRepairName (
825*7851SDana.Myers@Sun.COM     char                    *Name)
8263446Smrj {
827*7851SDana.Myers@Sun.COM     UINT32                  i;
828*7851SDana.Myers@Sun.COM     BOOLEAN                 FoundBadChar = FALSE;
829*7851SDana.Myers@Sun.COM 
8303446Smrj 
831*7851SDana.Myers@Sun.COM     ACPI_FUNCTION_NAME (UtRepairName);
832*7851SDana.Myers@Sun.COM 
833*7851SDana.Myers@Sun.COM 
834*7851SDana.Myers@Sun.COM     /* Check each character in the name */
8353446Smrj 
8363446Smrj     for (i = 0; i < ACPI_NAME_SIZE; i++)
8373446Smrj     {
838*7851SDana.Myers@Sun.COM         if (AcpiUtValidAcpiChar (Name[i], i))
839*7851SDana.Myers@Sun.COM         {
840*7851SDana.Myers@Sun.COM             continue;
841*7851SDana.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          */
848*7851SDana.Myers@Sun.COM         Name[i] = '*';
849*7851SDana.Myers@Sun.COM         FoundBadChar = TRUE;
850*7851SDana.Myers@Sun.COM     }
851*7851SDana.Myers@Sun.COM 
852*7851SDana.Myers@Sun.COM     if (FoundBadChar)
853*7851SDana.Myers@Sun.COM     {
854*7851SDana.Myers@Sun.COM         /* Report warning only if in strict mode or debug mode */
855*7851SDana.Myers@Sun.COM 
856*7851SDana.Myers@Sun.COM         if (!AcpiGbl_EnableInterpreterSlack)
8573446Smrj         {
858*7851SDana.Myers@Sun.COM             ACPI_WARNING ((AE_INFO,
859*7851SDana.Myers@Sun.COM                 "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
860*7851SDana.Myers@Sun.COM         }
861*7851SDana.Myers@Sun.COM         else
862*7851SDana.Myers@Sun.COM         {
863*7851SDana.Myers@Sun.COM             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
864*7851SDana.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) ||
11793446Smrj             (ACPI_GET_OBJECT_TYPE (ThisSourceObj) != 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             {
12403446Smrj                 return_ACPI_STATUS (AE_NO_MEMORY);
12413446Smrj             }
12423446Smrj         }
12433446Smrj     }
12443446Smrj 
12453446Smrj     /* We should never get here */
12463446Smrj 
12473446Smrj     return_ACPI_STATUS (AE_AML_INTERNAL);
12483446Smrj }
12493446Smrj 
12503446Smrj 
12513446Smrj /*******************************************************************************
12523446Smrj  *
12533446Smrj  * FUNCTION:    AcpiUtError, AcpiUtWarning, AcpiUtInfo
12543446Smrj  *
12553446Smrj  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
12563446Smrj  *              LineNumber          - Caller's line number (for error output)
12573446Smrj  *              Format              - Printf format string + additional args
12583446Smrj  *
12593446Smrj  * RETURN:      None
12603446Smrj  *
12613446Smrj  * DESCRIPTION: Print message with module/line/version info
12623446Smrj  *
12633446Smrj  ******************************************************************************/
12643446Smrj 
12653446Smrj void  ACPI_INTERNAL_VAR_XFACE
12663446Smrj AcpiUtError (
1267*7851SDana.Myers@Sun.COM     const char              *ModuleName,
12683446Smrj     UINT32                  LineNumber,
1269*7851SDana.Myers@Sun.COM     const char              *Format,
12703446Smrj     ...)
12713446Smrj {
12723446Smrj     va_list                 args;
12733446Smrj 
12743446Smrj 
12753446Smrj     AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber);
12763446Smrj 
12773446Smrj     va_start (args, Format);
12783446Smrj     AcpiOsVprintf (Format, args);
12793446Smrj     AcpiOsPrintf (" [%X]\n", ACPI_CA_VERSION);
1280*7851SDana.Myers@Sun.COM     va_end (args);
12813446Smrj }
12823446Smrj 
12833446Smrj void  ACPI_INTERNAL_VAR_XFACE
12843446Smrj AcpiUtException (
1285*7851SDana.Myers@Sun.COM     const char              *ModuleName,
12863446Smrj     UINT32                  LineNumber,
12873446Smrj     ACPI_STATUS             Status,
1288*7851SDana.Myers@Sun.COM     const char              *Format,
12893446Smrj     ...)
12903446Smrj {
12913446Smrj     va_list                 args;
12923446Smrj 
12933446Smrj 
12943446Smrj     AcpiOsPrintf ("ACPI Exception (%s-%04d): %s, ", ModuleName, LineNumber,
12953446Smrj         AcpiFormatException (Status));
12963446Smrj 
12973446Smrj     va_start (args, Format);
12983446Smrj     AcpiOsVprintf (Format, args);
12993446Smrj     AcpiOsPrintf (" [%X]\n", ACPI_CA_VERSION);
1300*7851SDana.Myers@Sun.COM     va_end (args);
13013446Smrj }
13023446Smrj 
13033446Smrj void  ACPI_INTERNAL_VAR_XFACE
13043446Smrj AcpiUtWarning (
1305*7851SDana.Myers@Sun.COM     const char              *ModuleName,
13063446Smrj     UINT32                  LineNumber,
1307*7851SDana.Myers@Sun.COM     const char              *Format,
13083446Smrj     ...)
13093446Smrj {
13103446Smrj     va_list                 args;
13113446Smrj 
13123446Smrj 
13133446Smrj     AcpiOsPrintf ("ACPI Warning (%s-%04d): ", ModuleName, LineNumber);
13143446Smrj 
13153446Smrj     va_start (args, Format);
13163446Smrj     AcpiOsVprintf (Format, args);
13173446Smrj     AcpiOsPrintf (" [%X]\n", ACPI_CA_VERSION);
1318*7851SDana.Myers@Sun.COM     va_end (args);
13193446Smrj }
13203446Smrj 
13213446Smrj void  ACPI_INTERNAL_VAR_XFACE
13223446Smrj AcpiUtInfo (
1323*7851SDana.Myers@Sun.COM     const char              *ModuleName,
13243446Smrj     UINT32                  LineNumber,
1325*7851SDana.Myers@Sun.COM     const char              *Format,
13263446Smrj     ...)
13273446Smrj {
13283446Smrj     va_list                 args;
13293446Smrj 
13303446Smrj 
1331*7851SDana.Myers@Sun.COM     /*
1332*7851SDana.Myers@Sun.COM      * Removed ModuleName, LineNumber, and acpica version, not needed
1333*7851SDana.Myers@Sun.COM      * for info output
1334*7851SDana.Myers@Sun.COM      */
1335*7851SDana.Myers@Sun.COM     AcpiOsPrintf ("ACPI: ");
13363446Smrj 
13373446Smrj     va_start (args, Format);
13383446Smrj     AcpiOsVprintf (Format, args);
1339*7851SDana.Myers@Sun.COM     AcpiOsPrintf ("\n");
1340*7851SDana.Myers@Sun.COM     va_end (args);
13413446Smrj }
13423446Smrj 
1343