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