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