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