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