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