xref: /freebsd/sys/contrib/dev/acpica/compiler/aslutils.c (revision 8f861da99cb9865b2f1ef6098ad074150f368c23)
1 
2 /******************************************************************************
3  *
4  * Module Name: aslutils -- compiler utilities
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2011, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44 
45 
46 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include "aslcompiler.y.h"
48 #include <contrib/dev/acpica/include/acdisasm.h>
49 #include <contrib/dev/acpica/include/acnamesp.h>
50 #include <contrib/dev/acpica/include/amlcode.h>
51 #include <contrib/dev/acpica/include/acapps.h>
52 
53 #define _COMPONENT          ACPI_COMPILER
54         ACPI_MODULE_NAME    ("aslutils")
55 
56 #ifdef _USE_BERKELEY_YACC
57 extern const char * const       AslCompilername[];
58 static const char * const       *yytname = &AslCompilername[254];
59 #else
60 extern const char * const       yytname[];
61 #endif
62 
63 char                        AslHexLookup[] =
64 {
65     '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
66 };
67 
68 
69 /* Local prototypes */
70 
71 static ACPI_STATUS
72 UtStrtoul64 (
73     char                    *String,
74     UINT32                  Base,
75     UINT64                  *RetInteger);
76 
77 static void
78 UtPadNameWithUnderscores (
79     char                    *NameSeg,
80     char                    *PaddedNameSeg);
81 
82 static void
83 UtAttachNameseg (
84     ACPI_PARSE_OBJECT       *Op,
85     char                    *Name);
86 
87 
88 /*******************************************************************************
89  *
90  * FUNCTION:    UtDisplaySupportedTables
91  *
92  * PARAMETERS:  None
93  *
94  * RETURN:      None
95  *
96  * DESCRIPTION: Print all supported ACPI table names.
97  *
98  ******************************************************************************/
99 
100 void
101 UtDisplaySupportedTables (
102     void)
103 {
104     ACPI_DMTABLE_DATA       *TableData;
105     UINT32                  i = 6;
106 
107 
108     printf ("\nACPI tables supported by iASL subsystems in "
109         "version %8.8X:\n"
110         "  ASL and Data Table compilers\n"
111         "  AML and Data Table disassemblers\n"
112         "  ACPI table template generator\n\n", ACPI_CA_VERSION);
113 
114     /* Special tables */
115 
116     printf ("%8u) %s    %s\n", 1, ACPI_SIG_DSDT, "Differentiated System Description Table");
117     printf ("%8u) %s    %s\n", 2, ACPI_SIG_SSDT, "Secondary System Description Table");
118     printf ("%8u) %s    %s\n", 3, ACPI_SIG_FADT, "Fixed ACPI Description Table (FADT)");
119     printf ("%8u) %s    %s\n", 4, ACPI_SIG_FACS, "Firmware ACPI Control Structure");
120     printf ("%8u) %s    %s\n", 5, ACPI_RSDP_NAME, "Root System Description Pointer");
121 
122     /* All data tables with common table header */
123 
124     for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
125     {
126         printf ("%8u) %s    %s\n", i, TableData->Signature, TableData->Name);
127         i++;
128     }
129 }
130 
131 
132 /*******************************************************************************
133  *
134  * FUNCTION:    AcpiPsDisplayConstantOpcodes
135  *
136  * PARAMETERS:  None
137  *
138  * RETURN:      None
139  *
140  * DESCRIPTION: Print AML opcodes that can be used in constant expressions.
141  *
142  ******************************************************************************/
143 
144 void
145 UtDisplayConstantOpcodes (
146     void)
147 {
148     UINT32                  i;
149 
150 
151     printf ("Constant expression opcode information\n\n");
152 
153     for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++)
154     {
155         if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT)
156         {
157             printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name);
158         }
159     }
160 }
161 
162 
163 /*******************************************************************************
164  *
165  * FUNCTION:    UtLocalCalloc
166  *
167  * PARAMETERS:  Size        - Bytes to be allocated
168  *
169  * RETURN:      Pointer to the allocated memory.  Guaranteed to be valid.
170  *
171  * DESCRIPTION: Allocate zero-initialized memory.  Aborts the compile on an
172  *              allocation failure, on the assumption that nothing more can be
173  *              accomplished.
174  *
175  ******************************************************************************/
176 
177 void *
178 UtLocalCalloc (
179     UINT32                  Size)
180 {
181     void                    *Allocated;
182 
183 
184     Allocated = ACPI_ALLOCATE_ZEROED (Size);
185     if (!Allocated)
186     {
187         AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
188             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
189             Gbl_InputByteCount, Gbl_CurrentColumn,
190             Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
191 
192         CmCleanupAndExit ();
193         exit (1);
194     }
195 
196     TotalAllocations++;
197     TotalAllocated += Size;
198     return (Allocated);
199 }
200 
201 
202 /*******************************************************************************
203  *
204  * FUNCTION:    UtBeginEvent
205  *
206  * PARAMETERS:  Name        - Ascii name of this event
207  *
208  * RETURN:      Event       - Event number (integer index)
209  *
210  * DESCRIPTION: Saves the current time with this event
211  *
212  ******************************************************************************/
213 
214 UINT8
215 UtBeginEvent (
216     char                    *Name)
217 {
218 
219     if (AslGbl_NextEvent >= ASL_NUM_EVENTS)
220     {
221         AcpiOsPrintf ("Ran out of compiler event structs!\n");
222         return (AslGbl_NextEvent);
223     }
224 
225     /* Init event with current (start) time */
226 
227     AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer ();
228     AslGbl_Events[AslGbl_NextEvent].EventName = Name;
229     AslGbl_Events[AslGbl_NextEvent].Valid = TRUE;
230 
231     return (AslGbl_NextEvent++);
232 }
233 
234 
235 /*******************************************************************************
236  *
237  * FUNCTION:    UtEndEvent
238  *
239  * PARAMETERS:  Event       - Event number (integer index)
240  *
241  * RETURN:      None
242  *
243  * DESCRIPTION: Saves the current time (end time) with this event
244  *
245  ******************************************************************************/
246 
247 void
248 UtEndEvent (
249     UINT8                  Event)
250 {
251 
252     if (Event >= ASL_NUM_EVENTS)
253     {
254         return;
255     }
256 
257     /* Insert end time for event */
258 
259     AslGbl_Events[Event].EndTime = AcpiOsGetTimer ();
260 }
261 
262 
263 /*******************************************************************************
264  *
265  * FUNCTION:    UtHexCharToValue
266  *
267  * PARAMETERS:  HexChar         - Hex character in Ascii
268  *
269  * RETURN:      The binary value of the hex character
270  *
271  * DESCRIPTION: Perform ascii-to-hex translation
272  *
273  ******************************************************************************/
274 
275 UINT8
276 UtHexCharToValue (
277     int                     HexChar)
278 {
279 
280     if (HexChar <= 0x39)
281     {
282         return ((UINT8) (HexChar - 0x30));
283     }
284 
285     if (HexChar <= 0x46)
286     {
287         return ((UINT8) (HexChar - 0x37));
288     }
289 
290     return ((UINT8) (HexChar - 0x57));
291 }
292 
293 
294 /*******************************************************************************
295  *
296  * FUNCTION:    UtConvertByteToHex
297  *
298  * PARAMETERS:  RawByte         - Binary data
299  *              Buffer          - Pointer to where the hex bytes will be stored
300  *
301  * RETURN:      Ascii hex byte is stored in Buffer.
302  *
303  * DESCRIPTION: Perform hex-to-ascii translation.  The return data is prefixed
304  *              with "0x"
305  *
306  ******************************************************************************/
307 
308 void
309 UtConvertByteToHex (
310     UINT8                   RawByte,
311     UINT8                   *Buffer)
312 {
313 
314     Buffer[0] = '0';
315     Buffer[1] = 'x';
316 
317     Buffer[2] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF];
318     Buffer[3] = (UINT8) AslHexLookup[RawByte & 0xF];
319 }
320 
321 
322 /*******************************************************************************
323  *
324  * FUNCTION:    UtConvertByteToAsmHex
325  *
326  * PARAMETERS:  RawByte         - Binary data
327  *              Buffer          - Pointer to where the hex bytes will be stored
328  *
329  * RETURN:      Ascii hex byte is stored in Buffer.
330  *
331  * DESCRIPTION: Perform hex-to-ascii translation.  The return data is prefixed
332  *              with "0x"
333  *
334  ******************************************************************************/
335 
336 void
337 UtConvertByteToAsmHex (
338     UINT8                   RawByte,
339     UINT8                   *Buffer)
340 {
341 
342     Buffer[0] = '0';
343     Buffer[1] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF];
344     Buffer[2] = (UINT8) AslHexLookup[RawByte & 0xF];
345     Buffer[3] = 'h';
346 }
347 
348 
349 /*******************************************************************************
350  *
351  * FUNCTION:    DbgPrint
352  *
353  * PARAMETERS:  Type            - Type of output
354  *              Fmt             - Printf format string
355  *              ...             - variable printf list
356  *
357  * RETURN:      None
358  *
359  * DESCRIPTION: Conditional print statement.  Prints to stderr only if the
360  *              debug flag is set.
361  *
362  ******************************************************************************/
363 
364 void
365 DbgPrint (
366     UINT32                  Type,
367     char                    *Fmt,
368     ...)
369 {
370     va_list                 Args;
371 
372 
373     va_start (Args, Fmt);
374 
375     if (!Gbl_DebugFlag)
376     {
377         return;
378     }
379 
380     if ((Type == ASL_PARSE_OUTPUT) &&
381         (!(AslCompilerdebug)))
382     {
383         return;
384     }
385 
386     (void) vfprintf (stderr, Fmt, Args);
387     va_end (Args);
388     return;
389 }
390 
391 
392 /*******************************************************************************
393  *
394  * FUNCTION:    UtPrintFormattedName
395  *
396  * PARAMETERS:  ParseOpcode         - Parser keyword ID
397  *              Level               - Indentation level
398  *
399  * RETURN:      None
400  *
401  * DESCRIPTION: Print the ascii name of the parse opcode.
402  *
403  ******************************************************************************/
404 
405 #define TEXT_OFFSET 10
406 
407 void
408 UtPrintFormattedName (
409     UINT16                  ParseOpcode,
410     UINT32                  Level)
411 {
412 
413     if (Level)
414     {
415         DbgPrint (ASL_TREE_OUTPUT,
416             "%*s", (3 * Level), " ");
417     }
418     DbgPrint (ASL_TREE_OUTPUT,
419         " %-20.20s", UtGetOpName (ParseOpcode));
420 
421     if (Level < TEXT_OFFSET)
422     {
423         DbgPrint (ASL_TREE_OUTPUT,
424             "%*s", (TEXT_OFFSET - Level) * 3, " ");
425     }
426 }
427 
428 
429 /*******************************************************************************
430  *
431  * FUNCTION:    UtSetParseOpName
432  *
433  * PARAMETERS:  Op
434  *
435  * RETURN:      None
436  *
437  * DESCRIPTION: Insert the ascii name of the parse opcode
438  *
439  ******************************************************************************/
440 
441 void
442 UtSetParseOpName (
443     ACPI_PARSE_OBJECT       *Op)
444 {
445 
446     strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
447         ACPI_MAX_PARSEOP_NAME);
448 }
449 
450 
451 /*******************************************************************************
452  *
453  * FUNCTION:    UtGetOpName
454  *
455  * PARAMETERS:  ParseOpcode         - Parser keyword ID
456  *
457  * RETURN:      Pointer to the opcode name
458  *
459  * DESCRIPTION: Get the ascii name of the parse opcode
460  *
461  ******************************************************************************/
462 
463 char *
464 UtGetOpName (
465     UINT32                  ParseOpcode)
466 {
467 
468     /*
469      * First entries (ASL_YYTNAME_START) in yytname are special reserved names.
470      * Ignore first 8 characters of the name
471      */
472     return ((char *) yytname
473         [(ParseOpcode - ASL_FIRST_PARSE_OPCODE) + ASL_YYTNAME_START] + 8);
474 }
475 
476 
477 /*******************************************************************************
478  *
479  * FUNCTION:    UtDisplaySummary
480  *
481  * PARAMETERS:  FileID          - ID of outpout file
482  *
483  * RETURN:      None
484  *
485  * DESCRIPTION: Display compilation statistics
486  *
487  ******************************************************************************/
488 
489 void
490 UtDisplaySummary (
491     UINT32                  FileId)
492 {
493 
494     if (FileId != ASL_FILE_STDOUT)
495     {
496         /* Compiler name and version number */
497 
498         FlPrintFile (FileId, "%s version %X%s\n",
499             ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH);
500     }
501 
502     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
503     {
504         FlPrintFile (FileId,
505             "Table Input:   %s - %u lines, %u bytes, %u fields\n",
506             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
507             Gbl_InputByteCount, Gbl_InputFieldCount);
508 
509         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
510         {
511             FlPrintFile (FileId,
512                 "Binary Output: %s - %u bytes\n\n",
513                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength);
514         }
515     }
516     else
517     {
518         /* Input/Output summary */
519 
520         FlPrintFile (FileId,
521             "ASL Input:  %s - %u lines, %u bytes, %u keywords\n",
522             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
523             Gbl_InputByteCount, TotalKeywords);
524 
525         /* AML summary */
526 
527         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
528         {
529             FlPrintFile (FileId,
530                 "AML Output: %s - %u bytes, %u named objects, %u executable opcodes\n\n",
531                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength,
532                 TotalNamedObjects, TotalExecutableOpcodes);
533         }
534     }
535 
536     /* Error summary */
537 
538     FlPrintFile (FileId,
539         "Compilation complete. %u Errors, %u Warnings, %u Remarks",
540         Gbl_ExceptionCount[ASL_ERROR],
541         Gbl_ExceptionCount[ASL_WARNING] +
542             Gbl_ExceptionCount[ASL_WARNING2] +
543             Gbl_ExceptionCount[ASL_WARNING3],
544         Gbl_ExceptionCount[ASL_REMARK]);
545 
546     if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
547     {
548         FlPrintFile (FileId,
549             ", %u Optimizations", Gbl_ExceptionCount[ASL_OPTIMIZATION]);
550     }
551 
552     FlPrintFile (FileId, "\n");
553 }
554 
555 
556 /*******************************************************************************
557  *
558  * FUNCTION:    UtDisplaySummary
559  *
560  * PARAMETERS:  Op              - Integer parse node
561  *              LowValue        - Smallest allowed value
562  *              HighValue       - Largest allowed value
563  *
564  * RETURN:      Op if OK, otherwise NULL
565  *
566  * DESCRIPTION: Check integer for an allowable range
567  *
568  ******************************************************************************/
569 
570 ACPI_PARSE_OBJECT *
571 UtCheckIntegerRange (
572     ACPI_PARSE_OBJECT       *Op,
573     UINT32                  LowValue,
574     UINT32                  HighValue)
575 {
576     char                    *ParseError = NULL;
577     char                    Buffer[64];
578 
579 
580     if (!Op)
581     {
582         return NULL;
583     }
584 
585     if (Op->Asl.Value.Integer < LowValue)
586     {
587         ParseError = "Value below valid range";
588         Op->Asl.Value.Integer = LowValue;
589     }
590 
591     if (Op->Asl.Value.Integer > HighValue)
592     {
593         ParseError = "Value above valid range";
594         Op->Asl.Value.Integer = HighValue;
595     }
596 
597     if (ParseError)
598     {
599         sprintf (Buffer, "%s 0x%X-0x%X", ParseError, LowValue, HighValue);
600         AslCompilererror (Buffer);
601 
602         return NULL;
603     }
604 
605     return Op;
606 }
607 
608 
609 /*******************************************************************************
610  *
611  * FUNCTION:    UtGetStringBuffer
612  *
613  * PARAMETERS:  Length          - Size of buffer requested
614  *
615  * RETURN:      Pointer to the buffer.  Aborts on allocation failure
616  *
617  * DESCRIPTION: Allocate a string buffer.  Bypass the local
618  *              dynamic memory manager for performance reasons (This has a
619  *              major impact on the speed of the compiler.)
620  *
621  ******************************************************************************/
622 
623 char *
624 UtGetStringBuffer (
625     UINT32                  Length)
626 {
627     char                    *Buffer;
628 
629 
630     if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
631     {
632         Gbl_StringCacheNext = UtLocalCalloc (ASL_STRING_CACHE_SIZE + Length);
633         Gbl_StringCacheLast = Gbl_StringCacheNext + ASL_STRING_CACHE_SIZE +
634                                 Length;
635     }
636 
637     Buffer = Gbl_StringCacheNext;
638     Gbl_StringCacheNext += Length;
639 
640     return (Buffer);
641 }
642 
643 
644 /*******************************************************************************
645  *
646  * FUNCTION:    UtInternalizeName
647  *
648  * PARAMETERS:  ExternalName            - Name to convert
649  *              ConvertedName           - Where the converted name is returned
650  *
651  * RETURN:      Status
652  *
653  * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
654  *
655  ******************************************************************************/
656 
657 ACPI_STATUS
658 UtInternalizeName (
659     char                    *ExternalName,
660     char                    **ConvertedName)
661 {
662     ACPI_NAMESTRING_INFO    Info;
663     ACPI_STATUS             Status;
664 
665 
666     if (!ExternalName)
667     {
668         return (AE_OK);
669     }
670 
671     /* Get the length of the new internal name */
672 
673     Info.ExternalName = ExternalName;
674     AcpiNsGetInternalNameLength (&Info);
675 
676     /* We need a segment to store the internal  name */
677 
678     Info.InternalName = UtGetStringBuffer (Info.Length);
679     if (!Info.InternalName)
680     {
681         return (AE_NO_MEMORY);
682     }
683 
684     /* Build the name */
685 
686     Status = AcpiNsBuildInternalName (&Info);
687     if (ACPI_FAILURE (Status))
688     {
689         return (Status);
690     }
691 
692     *ConvertedName = Info.InternalName;
693     return (AE_OK);
694 }
695 
696 
697 /*******************************************************************************
698  *
699  * FUNCTION:    UtPadNameWithUnderscores
700  *
701  * PARAMETERS:  NameSeg         - Input nameseg
702  *              PaddedNameSeg   - Output padded nameseg
703  *
704  * RETURN:      Padded nameseg.
705  *
706  * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
707  *              ACPI_NAME.
708  *
709  ******************************************************************************/
710 
711 static void
712 UtPadNameWithUnderscores (
713     char                    *NameSeg,
714     char                    *PaddedNameSeg)
715 {
716     UINT32                  i;
717 
718 
719     for (i = 0; (i < ACPI_NAME_SIZE); i++)
720     {
721         if (*NameSeg)
722         {
723             *PaddedNameSeg = *NameSeg;
724             NameSeg++;
725         }
726         else
727         {
728             *PaddedNameSeg = '_';
729         }
730         PaddedNameSeg++;
731     }
732 }
733 
734 
735 /*******************************************************************************
736  *
737  * FUNCTION:    UtAttachNameseg
738  *
739  * PARAMETERS:  Op              - Parent parse node
740  *              Name            - Full ExternalName
741  *
742  * RETURN:      None; Sets the NameSeg field in parent node
743  *
744  * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
745  *              in the NameSeg field of the Op.
746  *
747  ******************************************************************************/
748 
749 static void
750 UtAttachNameseg (
751     ACPI_PARSE_OBJECT       *Op,
752     char                    *Name)
753 {
754     char                    *NameSeg;
755     char                    PaddedNameSeg[4];
756 
757 
758     if (!Name)
759     {
760         return;
761     }
762 
763     /* Look for the last dot in the namepath */
764 
765     NameSeg = strrchr (Name, '.');
766     if (NameSeg)
767     {
768         /* Found last dot, we have also found the final nameseg */
769 
770         NameSeg++;
771         UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
772     }
773     else
774     {
775         /* No dots in the namepath, there is only a single nameseg. */
776         /* Handle prefixes */
777 
778         while ((*Name == '\\') || (*Name == '^'))
779         {
780             Name++;
781         }
782 
783         /* Remaing string should be one single nameseg */
784 
785         UtPadNameWithUnderscores (Name, PaddedNameSeg);
786     }
787 
788     strncpy (Op->Asl.NameSeg, PaddedNameSeg, 4);
789 }
790 
791 
792 /*******************************************************************************
793  *
794  * FUNCTION:    UtAttachNamepathToOwner
795  *
796  * PARAMETERS:  Op            - Parent parse node
797  *              NameOp        - Node that contains the name
798  *
799  * RETURN:      Sets the ExternalName and Namepath in the parent node
800  *
801  * DESCRIPTION: Store the name in two forms in the parent node:  The original
802  *              (external) name, and the internalized name that is used within
803  *              the ACPI namespace manager.
804  *
805  ******************************************************************************/
806 
807 void
808 UtAttachNamepathToOwner (
809     ACPI_PARSE_OBJECT       *Op,
810     ACPI_PARSE_OBJECT       *NameOp)
811 {
812     ACPI_STATUS             Status;
813 
814 
815     /* Full external path */
816 
817     Op->Asl.ExternalName = NameOp->Asl.Value.String;
818 
819     /* Save the NameOp for possible error reporting later */
820 
821     Op->Asl.ParentMethod = (void *) NameOp;
822 
823     /* Last nameseg of the path */
824 
825     UtAttachNameseg (Op, Op->Asl.ExternalName);
826 
827     /* Create internalized path */
828 
829     Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
830     if (ACPI_FAILURE (Status))
831     {
832         /* TBD: abort on no memory */
833     }
834 }
835 
836 
837 /*******************************************************************************
838  *
839  * FUNCTION:    UtDoConstant
840  *
841  * PARAMETERS:  String      - Hex, Octal, or Decimal string
842  *
843  * RETURN:      Converted Integer
844  *
845  * DESCRIPTION: Convert a string to an integer.  With error checking.
846  *
847  ******************************************************************************/
848 
849 UINT64
850 UtDoConstant (
851     char                    *String)
852 {
853     ACPI_STATUS             Status;
854     UINT64                  Converted;
855     char                    ErrBuf[64];
856 
857 
858     Status = UtStrtoul64 (String, 0, &Converted);
859     if (ACPI_FAILURE (Status))
860     {
861         sprintf (ErrBuf, "%s %s\n", "Conversion error:",
862             AcpiFormatException (Status));
863         AslCompilererror (ErrBuf);
864     }
865 
866     return (Converted);
867 }
868 
869 
870 /* TBD: use version in ACPI CA main code base? */
871 
872 /*******************************************************************************
873  *
874  * FUNCTION:    UtStrtoul64
875  *
876  * PARAMETERS:  String          - Null terminated string
877  *              Terminater      - Where a pointer to the terminating byte is
878  *                                returned
879  *              Base            - Radix of the string
880  *
881  * RETURN:      Converted value
882  *
883  * DESCRIPTION: Convert a string into an unsigned value.
884  *
885  ******************************************************************************/
886 
887 static ACPI_STATUS
888 UtStrtoul64 (
889     char                    *String,
890     UINT32                  Base,
891     UINT64                  *RetInteger)
892 {
893     UINT32                  Index;
894     UINT32                  Sign;
895     UINT64                  ReturnValue = 0;
896     ACPI_STATUS             Status = AE_OK;
897 
898 
899     *RetInteger = 0;
900 
901     switch (Base)
902     {
903     case 0:
904     case 8:
905     case 10:
906     case 16:
907         break;
908 
909     default:
910         /*
911          * The specified Base parameter is not in the domain of
912          * this function:
913          */
914         return (AE_BAD_PARAMETER);
915     }
916 
917     /* Skip over any white space in the buffer: */
918 
919     while (isspace ((int) *String) || *String == '\t')
920     {
921         ++String;
922     }
923 
924     /*
925      * The buffer may contain an optional plus or minus sign.
926      * If it does, then skip over it but remember what is was:
927      */
928     if (*String == '-')
929     {
930         Sign = NEGATIVE;
931         ++String;
932     }
933     else if (*String == '+')
934     {
935         ++String;
936         Sign = POSITIVE;
937     }
938     else
939     {
940         Sign = POSITIVE;
941     }
942 
943     /*
944      * If the input parameter Base is zero, then we need to
945      * determine if it is octal, decimal, or hexadecimal:
946      */
947     if (Base == 0)
948     {
949         if (*String == '0')
950         {
951             if (tolower ((int) *(++String)) == 'x')
952             {
953                 Base = 16;
954                 ++String;
955             }
956             else
957             {
958                 Base = 8;
959             }
960         }
961         else
962         {
963             Base = 10;
964         }
965     }
966 
967     /*
968      * For octal and hexadecimal bases, skip over the leading
969      * 0 or 0x, if they are present.
970      */
971     if (Base == 8 && *String == '0')
972     {
973         String++;
974     }
975 
976     if (Base == 16 &&
977         *String == '0' &&
978         tolower ((int) *(++String)) == 'x')
979     {
980         String++;
981     }
982 
983     /* Main loop: convert the string to an unsigned long */
984 
985     while (*String)
986     {
987         if (isdigit ((int) *String))
988         {
989             Index = ((UINT8) *String) - '0';
990         }
991         else
992         {
993             Index = (UINT8) toupper ((int) *String);
994             if (isupper ((int) Index))
995             {
996                 Index = Index - 'A' + 10;
997             }
998             else
999             {
1000                 goto ErrorExit;
1001             }
1002         }
1003 
1004         if (Index >= Base)
1005         {
1006             goto ErrorExit;
1007         }
1008 
1009         /* Check to see if value is out of range: */
1010 
1011         if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
1012                             (UINT64) Base))
1013         {
1014             goto ErrorExit;
1015         }
1016         else
1017         {
1018             ReturnValue *= Base;
1019             ReturnValue += Index;
1020         }
1021 
1022         ++String;
1023     }
1024 
1025 
1026     /* If a minus sign was present, then "the conversion is negated": */
1027 
1028     if (Sign == NEGATIVE)
1029     {
1030         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
1031     }
1032 
1033     *RetInteger = ReturnValue;
1034     return (Status);
1035 
1036 
1037 ErrorExit:
1038     switch (Base)
1039     {
1040     case 8:
1041         Status = AE_BAD_OCTAL_CONSTANT;
1042         break;
1043 
1044     case 10:
1045         Status = AE_BAD_DECIMAL_CONSTANT;
1046         break;
1047 
1048     case 16:
1049         Status = AE_BAD_HEX_CONSTANT;
1050         break;
1051 
1052     default:
1053         /* Base validated above */
1054         break;
1055     }
1056 
1057     return (Status);
1058 }
1059 
1060 
1061