xref: /titanic_44/usr/src/uts/intel/io/acpica/utilities/utmisc.c (revision 5fd03bc0f2e00e7ba02316c2e08f45d52aab15db)
1 /*******************************************************************************
2  *
3  * Module Name: utmisc - common utility procedures
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2011, 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 "acpi.h"
48 #include "accommon.h"
49 #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 #endif
470 
471 
472 /*******************************************************************************
473  *
474  * FUNCTION:    AcpiUtPrintString
475  *
476  * PARAMETERS:  String          - Null terminated ASCII string
477  *              MaxLength       - Maximum output length
478  *
479  * RETURN:      None
480  *
481  * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
482  *              sequences.
483  *
484  ******************************************************************************/
485 
486 void
487 AcpiUtPrintString (
488     char                    *String,
489     UINT8                   MaxLength)
490 {
491     UINT32                  i;
492 
493 
494     if (!String)
495     {
496         AcpiOsPrintf ("<\"NULL STRING PTR\">");
497         return;
498     }
499 
500     AcpiOsPrintf ("\"");
501     for (i = 0; String[i] && (i < MaxLength); i++)
502     {
503         /* Escape sequences */
504 
505         switch (String[i])
506         {
507         case 0x07:
508             AcpiOsPrintf ("\\a");       /* BELL */
509             break;
510 
511         case 0x08:
512             AcpiOsPrintf ("\\b");       /* BACKSPACE */
513             break;
514 
515         case 0x0C:
516             AcpiOsPrintf ("\\f");       /* FORMFEED */
517             break;
518 
519         case 0x0A:
520             AcpiOsPrintf ("\\n");       /* LINEFEED */
521             break;
522 
523         case 0x0D:
524             AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
525             break;
526 
527         case 0x09:
528             AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
529             break;
530 
531         case 0x0B:
532             AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
533             break;
534 
535         case '\'':                      /* Single Quote */
536         case '\"':                      /* Double Quote */
537         case '\\':                      /* Backslash */
538             AcpiOsPrintf ("\\%c", (int) String[i]);
539             break;
540 
541         default:
542 
543             /* Check for printable character or hex escape */
544 
545             if (ACPI_IS_PRINT (String[i]))
546             {
547                 /* This is a normal character */
548 
549                 AcpiOsPrintf ("%c", (int) String[i]);
550             }
551             else
552             {
553                 /* All others will be Hex escapes */
554 
555                 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
556             }
557             break;
558         }
559     }
560     AcpiOsPrintf ("\"");
561 
562     if (i == MaxLength && String[i])
563     {
564         AcpiOsPrintf ("...");
565     }
566 }
567 
568 
569 /*******************************************************************************
570  *
571  * FUNCTION:    AcpiUtDwordByteSwap
572  *
573  * PARAMETERS:  Value           - Value to be converted
574  *
575  * RETURN:      UINT32 integer with bytes swapped
576  *
577  * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
578  *
579  ******************************************************************************/
580 
581 UINT32
582 AcpiUtDwordByteSwap (
583     UINT32                  Value)
584 {
585     union
586     {
587         UINT32              Value;
588         UINT8               Bytes[4];
589     } Out;
590     union
591     {
592         UINT32              Value;
593         UINT8               Bytes[4];
594     } In;
595 
596 
597     ACPI_FUNCTION_ENTRY ();
598 
599 
600     In.Value = Value;
601 
602     Out.Bytes[0] = In.Bytes[3];
603     Out.Bytes[1] = In.Bytes[2];
604     Out.Bytes[2] = In.Bytes[1];
605     Out.Bytes[3] = In.Bytes[0];
606 
607     return (Out.Value);
608 }
609 
610 
611 /*******************************************************************************
612  *
613  * FUNCTION:    AcpiUtSetIntegerWidth
614  *
615  * PARAMETERS:  Revision            From DSDT header
616  *
617  * RETURN:      None
618  *
619  * DESCRIPTION: Set the global integer bit width based upon the revision
620  *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
621  *              For Revision 2 and above, Integers are 64 bits.  Yes, this
622  *              makes a difference.
623  *
624  ******************************************************************************/
625 
626 void
627 AcpiUtSetIntegerWidth (
628     UINT8                   Revision)
629 {
630 
631     if (Revision < 2)
632     {
633         /* 32-bit case */
634 
635         AcpiGbl_IntegerBitWidth    = 32;
636         AcpiGbl_IntegerNybbleWidth = 8;
637         AcpiGbl_IntegerByteWidth   = 4;
638     }
639     else
640     {
641         /* 64-bit case (ACPI 2.0+) */
642 
643         AcpiGbl_IntegerBitWidth    = 64;
644         AcpiGbl_IntegerNybbleWidth = 16;
645         AcpiGbl_IntegerByteWidth   = 8;
646     }
647 }
648 
649 
650 #ifdef ACPI_DEBUG_OUTPUT
651 /*******************************************************************************
652  *
653  * FUNCTION:    AcpiUtDisplayInitPathname
654  *
655  * PARAMETERS:  Type                - Object type of the node
656  *              ObjHandle           - Handle whose pathname will be displayed
657  *              Path                - Additional path string to be appended.
658  *                                      (NULL if no extra path)
659  *
660  * RETURN:      ACPI_STATUS
661  *
662  * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
663  *
664  ******************************************************************************/
665 
666 void
667 AcpiUtDisplayInitPathname (
668     UINT8                   Type,
669     ACPI_NAMESPACE_NODE     *ObjHandle,
670     char                    *Path)
671 {
672     ACPI_STATUS             Status;
673     ACPI_BUFFER             Buffer;
674 
675 
676     ACPI_FUNCTION_ENTRY ();
677 
678 
679     /* Only print the path if the appropriate debug level is enabled */
680 
681     if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
682     {
683         return;
684     }
685 
686     /* Get the full pathname to the node */
687 
688     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
689     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
690     if (ACPI_FAILURE (Status))
691     {
692         return;
693     }
694 
695     /* Print what we're doing */
696 
697     switch (Type)
698     {
699     case ACPI_TYPE_METHOD:
700         AcpiOsPrintf ("Executing    ");
701         break;
702 
703     default:
704         AcpiOsPrintf ("Initializing ");
705         break;
706     }
707 
708     /* Print the object type and pathname */
709 
710     AcpiOsPrintf ("%-12s  %s",
711         AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
712 
713     /* Extra path is used to append names like _STA, _INI, etc. */
714 
715     if (Path)
716     {
717         AcpiOsPrintf (".%s", Path);
718     }
719     AcpiOsPrintf ("\n");
720 
721     ACPI_FREE (Buffer.Pointer);
722 }
723 #endif
724 
725 
726 /*******************************************************************************
727  *
728  * FUNCTION:    AcpiUtValidAcpiChar
729  *
730  * PARAMETERS:  Char            - The character to be examined
731  *              Position        - Byte position (0-3)
732  *
733  * RETURN:      TRUE if the character is valid, FALSE otherwise
734  *
735  * DESCRIPTION: Check for a valid ACPI character. Must be one of:
736  *              1) Upper case alpha
737  *              2) numeric
738  *              3) underscore
739  *
740  *              We allow a '!' as the last character because of the ASF! table
741  *
742  ******************************************************************************/
743 
744 BOOLEAN
745 AcpiUtValidAcpiChar (
746     char                    Character,
747     UINT32                  Position)
748 {
749 
750     if (!((Character >= 'A' && Character <= 'Z') ||
751           (Character >= '0' && Character <= '9') ||
752           (Character == '_')))
753     {
754         /* Allow a '!' in the last position */
755 
756         if (Character == '!' && Position == 3)
757         {
758             return (TRUE);
759         }
760 
761         return (FALSE);
762     }
763 
764     return (TRUE);
765 }
766 
767 
768 /*******************************************************************************
769  *
770  * FUNCTION:    AcpiUtValidAcpiName
771  *
772  * PARAMETERS:  Name            - The name to be examined
773  *
774  * RETURN:      TRUE if the name is valid, FALSE otherwise
775  *
776  * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
777  *              1) Upper case alpha
778  *              2) numeric
779  *              3) underscore
780  *
781  ******************************************************************************/
782 
783 BOOLEAN
784 AcpiUtValidAcpiName (
785     UINT32                  Name)
786 {
787     UINT32                  i;
788 
789 
790     ACPI_FUNCTION_ENTRY ();
791 
792 
793     for (i = 0; i < ACPI_NAME_SIZE; i++)
794     {
795         if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i))
796         {
797             return (FALSE);
798         }
799     }
800 
801     return (TRUE);
802 }
803 
804 
805 /*******************************************************************************
806  *
807  * FUNCTION:    AcpiUtRepairName
808  *
809  * PARAMETERS:  Name            - The ACPI name to be repaired
810  *
811  * RETURN:      Repaired version of the name
812  *
813  * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
814  *              return the new name. NOTE: the Name parameter must reside in
815  *              read/write memory, cannot be a const.
816  *
817  * An ACPI Name must consist of valid ACPI characters. We will repair the name
818  * if necessary because we don't want to abort because of this, but we want
819  * all namespace names to be printable. A warning message is appropriate.
820  *
821  * This issue came up because there are in fact machines that exhibit
822  * this problem, and we want to be able to enable ACPI support for them,
823  * even though there are a few bad names.
824  *
825  ******************************************************************************/
826 
827 void
828 AcpiUtRepairName (
829     char                    *Name)
830 {
831     UINT32                  i;
832     BOOLEAN                 FoundBadChar = FALSE;
833 
834 
835     ACPI_FUNCTION_NAME (UtRepairName);
836 
837 
838     /* Check each character in the name */
839 
840     for (i = 0; i < ACPI_NAME_SIZE; i++)
841     {
842         if (AcpiUtValidAcpiChar (Name[i], i))
843         {
844             continue;
845         }
846 
847         /*
848          * Replace a bad character with something printable, yet technically
849          * still invalid. This prevents any collisions with existing "good"
850          * names in the namespace.
851          */
852         Name[i] = '*';
853         FoundBadChar = TRUE;
854     }
855 
856     if (FoundBadChar)
857     {
858         /* Report warning only if in strict mode or debug mode */
859 
860         if (!AcpiGbl_EnableInterpreterSlack)
861         {
862             ACPI_WARNING ((AE_INFO,
863                 "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
864         }
865         else
866         {
867             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
868                 "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
869         }
870     }
871 }
872 
873 
874 /*******************************************************************************
875  *
876  * FUNCTION:    AcpiUtStrtoul64
877  *
878  * PARAMETERS:  String          - Null terminated string
879  *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
880  *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
881  *              RetInteger      - Where the converted integer is returned
882  *
883  * RETURN:      Status and Converted value
884  *
885  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
886  *              32-bit or 64-bit conversion, depending on the current mode
887  *              of the interpreter.
888  *              NOTE: Does not support Octal strings, not needed.
889  *
890  ******************************************************************************/
891 
892 ACPI_STATUS
893 AcpiUtStrtoul64 (
894     char                    *String,
895     UINT32                  Base,
896     UINT64                  *RetInteger)
897 {
898     UINT32                  ThisDigit = 0;
899     UINT64                  ReturnValue = 0;
900     UINT64                  Quotient;
901     UINT64                  Dividend;
902     UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
903     UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
904     UINT8                   ValidDigits = 0;
905     UINT8                   SignOf0x = 0;
906     UINT8                   Term = 0;
907 
908 
909     ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
910 
911 
912     switch (Base)
913     {
914     case ACPI_ANY_BASE:
915     case 16:
916         break;
917 
918     default:
919         /* Invalid Base */
920         return_ACPI_STATUS (AE_BAD_PARAMETER);
921     }
922 
923     if (!String)
924     {
925         goto ErrorExit;
926     }
927 
928     /* Skip over any white space in the buffer */
929 
930     while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
931     {
932         String++;
933     }
934 
935     if (ToIntegerOp)
936     {
937         /*
938          * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
939          * We need to determine if it is decimal or hexadecimal.
940          */
941         if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
942         {
943             SignOf0x = 1;
944             Base = 16;
945 
946             /* Skip over the leading '0x' */
947             String += 2;
948         }
949         else
950         {
951             Base = 10;
952         }
953     }
954 
955     /* Any string left? Check that '0x' is not followed by white space. */
956 
957     if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
958     {
959         if (ToIntegerOp)
960         {
961             goto ErrorExit;
962         }
963         else
964         {
965             goto AllDone;
966         }
967     }
968 
969     /*
970      * Perform a 32-bit or 64-bit conversion, depending upon the current
971      * execution mode of the interpreter
972      */
973     Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
974 
975     /* Main loop: convert the string to a 32- or 64-bit integer */
976 
977     while (*String)
978     {
979         if (ACPI_IS_DIGIT (*String))
980         {
981             /* Convert ASCII 0-9 to Decimal value */
982 
983             ThisDigit = ((UINT8) *String) - '0';
984         }
985         else if (Base == 10)
986         {
987             /* Digit is out of range; possible in ToInteger case only */
988 
989             Term = 1;
990         }
991         else
992         {
993             ThisDigit = (UINT8) ACPI_TOUPPER (*String);
994             if (ACPI_IS_XDIGIT ((char) ThisDigit))
995             {
996                 /* Convert ASCII Hex char to value */
997 
998                 ThisDigit = ThisDigit - 'A' + 10;
999             }
1000             else
1001             {
1002                 Term = 1;
1003             }
1004         }
1005 
1006         if (Term)
1007         {
1008             if (ToIntegerOp)
1009             {
1010                 goto ErrorExit;
1011             }
1012             else
1013             {
1014                 break;
1015             }
1016         }
1017         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
1018         {
1019             /* Skip zeros */
1020             String++;
1021             continue;
1022         }
1023 
1024         ValidDigits++;
1025 
1026         if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
1027         {
1028             /*
1029              * This is ToInteger operation case.
1030              * No any restrictions for string-to-integer conversion,
1031              * see ACPI spec.
1032              */
1033             goto ErrorExit;
1034         }
1035 
1036         /* Divide the digit into the correct position */
1037 
1038         (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
1039                     Base, &Quotient, NULL);
1040 
1041         if (ReturnValue > Quotient)
1042         {
1043             if (ToIntegerOp)
1044             {
1045                 goto ErrorExit;
1046             }
1047             else
1048             {
1049                 break;
1050             }
1051         }
1052 
1053         ReturnValue *= Base;
1054         ReturnValue += ThisDigit;
1055         String++;
1056     }
1057 
1058     /* All done, normal exit */
1059 
1060 AllDone:
1061 
1062     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
1063         ACPI_FORMAT_UINT64 (ReturnValue)));
1064 
1065     *RetInteger = ReturnValue;
1066     return_ACPI_STATUS (AE_OK);
1067 
1068 
1069 ErrorExit:
1070     /* Base was set/validated above */
1071 
1072     if (Base == 10)
1073     {
1074         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
1075     }
1076     else
1077     {
1078         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
1079     }
1080 }
1081 
1082 
1083 /*******************************************************************************
1084  *
1085  * FUNCTION:    AcpiUtCreateUpdateStateAndPush
1086  *
1087  * PARAMETERS:  Object          - Object to be added to the new state
1088  *              Action          - Increment/Decrement
1089  *              StateList       - List the state will be added to
1090  *
1091  * RETURN:      Status
1092  *
1093  * DESCRIPTION: Create a new state and push it
1094  *
1095  ******************************************************************************/
1096 
1097 ACPI_STATUS
1098 AcpiUtCreateUpdateStateAndPush (
1099     ACPI_OPERAND_OBJECT     *Object,
1100     UINT16                  Action,
1101     ACPI_GENERIC_STATE      **StateList)
1102 {
1103     ACPI_GENERIC_STATE       *State;
1104 
1105 
1106     ACPI_FUNCTION_ENTRY ();
1107 
1108 
1109     /* Ignore null objects; these are expected */
1110 
1111     if (!Object)
1112     {
1113         return (AE_OK);
1114     }
1115 
1116     State = AcpiUtCreateUpdateState (Object, Action);
1117     if (!State)
1118     {
1119         return (AE_NO_MEMORY);
1120     }
1121 
1122     AcpiUtPushGenericState (StateList, State);
1123     return (AE_OK);
1124 }
1125 
1126 
1127 /*******************************************************************************
1128  *
1129  * FUNCTION:    AcpiUtWalkPackageTree
1130  *
1131  * PARAMETERS:  SourceObject        - The package to walk
1132  *              TargetObject        - Target object (if package is being copied)
1133  *              WalkCallback        - Called once for each package element
1134  *              Context             - Passed to the callback function
1135  *
1136  * RETURN:      Status
1137  *
1138  * DESCRIPTION: Walk through a package
1139  *
1140  ******************************************************************************/
1141 
1142 ACPI_STATUS
1143 AcpiUtWalkPackageTree (
1144     ACPI_OPERAND_OBJECT     *SourceObject,
1145     void                    *TargetObject,
1146     ACPI_PKG_CALLBACK       WalkCallback,
1147     void                    *Context)
1148 {
1149     ACPI_STATUS             Status = AE_OK;
1150     ACPI_GENERIC_STATE      *StateList = NULL;
1151     ACPI_GENERIC_STATE      *State;
1152     UINT32                  ThisIndex;
1153     ACPI_OPERAND_OBJECT     *ThisSourceObj;
1154 
1155 
1156     ACPI_FUNCTION_TRACE (UtWalkPackageTree);
1157 
1158 
1159     State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
1160     if (!State)
1161     {
1162         return_ACPI_STATUS (AE_NO_MEMORY);
1163     }
1164 
1165     while (State)
1166     {
1167         /* Get one element of the package */
1168 
1169         ThisIndex     = State->Pkg.Index;
1170         ThisSourceObj = (ACPI_OPERAND_OBJECT *)
1171                         State->Pkg.SourceObject->Package.Elements[ThisIndex];
1172 
1173         /*
1174          * Check for:
1175          * 1) An uninitialized package element.  It is completely
1176          *    legal to declare a package and leave it uninitialized
1177          * 2) Not an internal object - can be a namespace node instead
1178          * 3) Any type other than a package.  Packages are handled in else
1179          *    case below.
1180          */
1181         if ((!ThisSourceObj) ||
1182             (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
1183             (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
1184         {
1185             Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
1186                                     State, Context);
1187             if (ACPI_FAILURE (Status))
1188             {
1189                 return_ACPI_STATUS (Status);
1190             }
1191 
1192             State->Pkg.Index++;
1193             while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
1194             {
1195                 /*
1196                  * We've handled all of the objects at this level,  This means
1197                  * that we have just completed a package.  That package may
1198                  * have contained one or more packages itself.
1199                  *
1200                  * Delete this state and pop the previous state (package).
1201                  */
1202                 AcpiUtDeleteGenericState (State);
1203                 State = AcpiUtPopGenericState (&StateList);
1204 
1205                 /* Finished when there are no more states */
1206 
1207                 if (!State)
1208                 {
1209                     /*
1210                      * We have handled all of the objects in the top level
1211                      * package just add the length of the package objects
1212                      * and exit
1213                      */
1214                     return_ACPI_STATUS (AE_OK);
1215                 }
1216 
1217                 /*
1218                  * Go back up a level and move the index past the just
1219                  * completed package object.
1220                  */
1221                 State->Pkg.Index++;
1222             }
1223         }
1224         else
1225         {
1226             /* This is a subobject of type package */
1227 
1228             Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
1229                                         State, Context);
1230             if (ACPI_FAILURE (Status))
1231             {
1232                 return_ACPI_STATUS (Status);
1233             }
1234 
1235             /*
1236              * Push the current state and create a new one
1237              * The callback above returned a new target package object.
1238              */
1239             AcpiUtPushGenericState (&StateList, State);
1240             State = AcpiUtCreatePkgState (ThisSourceObj,
1241                                             State->Pkg.ThisTargetObj, 0);
1242             if (!State)
1243             {
1244                 /* Free any stacked Update State objects */
1245 
1246                 while (StateList)
1247                 {
1248                     State = AcpiUtPopGenericState (&StateList);
1249                     AcpiUtDeleteGenericState (State);
1250                 }
1251                 return_ACPI_STATUS (AE_NO_MEMORY);
1252             }
1253         }
1254     }
1255 
1256     /* We should never get here */
1257 
1258     return_ACPI_STATUS (AE_AML_INTERNAL);
1259 }
1260 
1261 
1262