]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/compiler/aslutils.c
Merge ACPICA 20120711.
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / compiler / aslutils.c
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:    UtDisplayConstantOpcodes
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 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
308  *                                    stored
309  *
310  * RETURN:      Ascii hex byte is stored in Buffer.
311  *
312  * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
313  *              with "0x"
314  *
315  ******************************************************************************/
316
317 void
318 UtConvertByteToHex (
319     UINT8                   RawByte,
320     UINT8                   *Buffer)
321 {
322
323     Buffer[0] = '0';
324     Buffer[1] = 'x';
325
326     Buffer[2] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF];
327     Buffer[3] = (UINT8) AslHexLookup[RawByte & 0xF];
328 }
329
330
331 /*******************************************************************************
332  *
333  * FUNCTION:    UtConvertByteToAsmHex
334  *
335  * PARAMETERS:  RawByte             - Binary data
336  *              Buffer              - Pointer to where the hex bytes will be
337  *                                    stored
338  *
339  * RETURN:      Ascii hex byte is stored in Buffer.
340  *
341  * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed
342  *              with "0x"
343  *
344  ******************************************************************************/
345
346 void
347 UtConvertByteToAsmHex (
348     UINT8                   RawByte,
349     UINT8                   *Buffer)
350 {
351
352     Buffer[0] = '0';
353     Buffer[1] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF];
354     Buffer[2] = (UINT8) AslHexLookup[RawByte & 0xF];
355     Buffer[3] = 'h';
356 }
357
358
359 /*******************************************************************************
360  *
361  * FUNCTION:    DbgPrint
362  *
363  * PARAMETERS:  Type                - Type of output
364  *              Fmt                 - Printf format string
365  *              ...                 - variable printf list
366  *
367  * RETURN:      None
368  *
369  * DESCRIPTION: Conditional print statement. Prints to stderr only if the
370  *              debug flag is set.
371  *
372  ******************************************************************************/
373
374 void
375 DbgPrint (
376     UINT32                  Type,
377     char                    *Fmt,
378     ...)
379 {
380     va_list                 Args;
381
382
383     va_start (Args, Fmt);
384
385     if (!Gbl_DebugFlag)
386     {
387         return;
388     }
389
390     if ((Type == ASL_PARSE_OUTPUT) &&
391         (!(AslCompilerdebug)))
392     {
393         return;
394     }
395
396     (void) vfprintf (stderr, Fmt, Args);
397     va_end (Args);
398     return;
399 }
400
401
402 /*******************************************************************************
403  *
404  * FUNCTION:    UtPrintFormattedName
405  *
406  * PARAMETERS:  ParseOpcode         - Parser keyword ID
407  *              Level               - Indentation level
408  *
409  * RETURN:      None
410  *
411  * DESCRIPTION: Print the ascii name of the parse opcode.
412  *
413  ******************************************************************************/
414
415 #define TEXT_OFFSET 10
416
417 void
418 UtPrintFormattedName (
419     UINT16                  ParseOpcode,
420     UINT32                  Level)
421 {
422
423     if (Level)
424     {
425         DbgPrint (ASL_TREE_OUTPUT,
426             "%*s", (3 * Level), " ");
427     }
428     DbgPrint (ASL_TREE_OUTPUT,
429         " %-20.20s", UtGetOpName (ParseOpcode));
430
431     if (Level < TEXT_OFFSET)
432     {
433         DbgPrint (ASL_TREE_OUTPUT,
434             "%*s", (TEXT_OFFSET - Level) * 3, " ");
435     }
436 }
437
438
439 /*******************************************************************************
440  *
441  * FUNCTION:    UtSetParseOpName
442  *
443  * PARAMETERS:  Op                  - Parse op to be named.
444  *
445  * RETURN:      None
446  *
447  * DESCRIPTION: Insert the ascii name of the parse opcode
448  *
449  ******************************************************************************/
450
451 void
452 UtSetParseOpName (
453     ACPI_PARSE_OBJECT       *Op)
454 {
455
456     strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
457         ACPI_MAX_PARSEOP_NAME);
458 }
459
460
461 /*******************************************************************************
462  *
463  * FUNCTION:    UtDisplaySummary
464  *
465  * PARAMETERS:  FileID              - ID of outpout file
466  *
467  * RETURN:      None
468  *
469  * DESCRIPTION: Display compilation statistics
470  *
471  ******************************************************************************/
472
473 void
474 UtDisplaySummary (
475     UINT32                  FileId)
476 {
477     UINT32                  i;
478
479
480     if (FileId != ASL_FILE_STDOUT)
481     {
482         /* Compiler name and version number */
483
484         FlPrintFile (FileId, "%s version %X%s\n\n",
485             ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH);
486     }
487
488     /* Summary of main input and output files */
489
490     if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA)
491     {
492         FlPrintFile (FileId,
493             "%-14s %s - %u lines, %u bytes, %u fields\n",
494             "Table Input:",
495             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
496             Gbl_InputByteCount, Gbl_InputFieldCount);
497
498         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
499         {
500             FlPrintFile (FileId,
501                 "%-14s %s - %u bytes\n",
502                 "Binary Output:",
503                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength);
504         }
505     }
506     else
507     {
508         FlPrintFile (FileId,
509             "%-14s %s - %u lines, %u bytes, %u keywords\n",
510             "ASL Input:",
511             Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber,
512             Gbl_InputByteCount, TotalKeywords);
513
514         /* AML summary */
515
516         if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors))
517         {
518             FlPrintFile (FileId,
519                 "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n",
520                 "AML Output:",
521                 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength,
522                 TotalNamedObjects, TotalExecutableOpcodes);
523         }
524     }
525
526     /* Display summary of any optional files */
527
528     for (i = ASL_FILE_SOURCE_OUTPUT; i <= ASL_MAX_FILE_TYPE; i++)
529     {
530         if (!Gbl_Files[i].Filename || !Gbl_Files[i].Handle)
531         {
532             continue;
533         }
534
535         /* .SRC is a temp file unless specifically requested */
536
537         if ((i == ASL_FILE_SOURCE_OUTPUT) && (!Gbl_SourceOutputFlag))
538         {
539             continue;
540         }
541
542         /* .I is a temp file unless specifically requested */
543
544         if ((i == ASL_FILE_PREPROCESSOR) && (!Gbl_PreprocessorOutputFlag))
545         {
546             continue;
547         }
548
549         FlPrintFile (FileId, "%14s %s - %u bytes\n",
550             AslFileTypeNames [i],
551             Gbl_Files[i].Filename, FlGetFileSize (i));
552     }
553
554     /* Error summary */
555
556     FlPrintFile (FileId,
557         "\nCompilation complete. %u Errors, %u Warnings, %u Remarks",
558         Gbl_ExceptionCount[ASL_ERROR],
559         Gbl_ExceptionCount[ASL_WARNING] +
560             Gbl_ExceptionCount[ASL_WARNING2] +
561             Gbl_ExceptionCount[ASL_WARNING3],
562         Gbl_ExceptionCount[ASL_REMARK]);
563
564     if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA)
565     {
566         FlPrintFile (FileId,
567             ", %u Optimizations", Gbl_ExceptionCount[ASL_OPTIMIZATION]);
568     }
569
570     FlPrintFile (FileId, "\n");
571 }
572
573
574 /*******************************************************************************
575  *
576  * FUNCTION:    UtCheckIntegerRange
577  *
578  * PARAMETERS:  Op                  - Integer parse node
579  *              LowValue            - Smallest allowed value
580  *              HighValue           - Largest allowed value
581  *
582  * RETURN:      Op if OK, otherwise NULL
583  *
584  * DESCRIPTION: Check integer for an allowable range
585  *
586  ******************************************************************************/
587
588 ACPI_PARSE_OBJECT *
589 UtCheckIntegerRange (
590     ACPI_PARSE_OBJECT       *Op,
591     UINT32                  LowValue,
592     UINT32                  HighValue)
593 {
594     char                    *ParseError = NULL;
595     char                    Buffer[64];
596
597
598     if (!Op)
599     {
600         return NULL;
601     }
602
603     if (Op->Asl.Value.Integer < LowValue)
604     {
605         ParseError = "Value below valid range";
606         Op->Asl.Value.Integer = LowValue;
607     }
608
609     if (Op->Asl.Value.Integer > HighValue)
610     {
611         ParseError = "Value above valid range";
612         Op->Asl.Value.Integer = HighValue;
613     }
614
615     if (ParseError)
616     {
617         sprintf (Buffer, "%s 0x%X-0x%X", ParseError, LowValue, HighValue);
618         AslCompilererror (Buffer);
619
620         return NULL;
621     }
622
623     return Op;
624 }
625
626
627 /*******************************************************************************
628  *
629  * FUNCTION:    UtGetStringBuffer
630  *
631  * PARAMETERS:  Length              - Size of buffer requested
632  *
633  * RETURN:      Pointer to the buffer. Aborts on allocation failure
634  *
635  * DESCRIPTION: Allocate a string buffer. Bypass the local
636  *              dynamic memory manager for performance reasons (This has a
637  *              major impact on the speed of the compiler.)
638  *
639  ******************************************************************************/
640
641 char *
642 UtGetStringBuffer (
643     UINT32                  Length)
644 {
645     char                    *Buffer;
646
647
648     if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
649     {
650         Gbl_StringCacheNext = UtLocalCalloc (ASL_STRING_CACHE_SIZE + Length);
651         Gbl_StringCacheLast = Gbl_StringCacheNext + ASL_STRING_CACHE_SIZE +
652                                 Length;
653     }
654
655     Buffer = Gbl_StringCacheNext;
656     Gbl_StringCacheNext += Length;
657
658     return (Buffer);
659 }
660
661
662 /*******************************************************************************
663  *
664  * FUNCTION:    UtInternalizeName
665  *
666  * PARAMETERS:  ExternalName        - Name to convert
667  *              ConvertedName       - Where the converted name is returned
668  *
669  * RETURN:      Status
670  *
671  * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
672  *
673  ******************************************************************************/
674
675 ACPI_STATUS
676 UtInternalizeName (
677     char                    *ExternalName,
678     char                    **ConvertedName)
679 {
680     ACPI_NAMESTRING_INFO    Info;
681     ACPI_STATUS             Status;
682
683
684     if (!ExternalName)
685     {
686         return (AE_OK);
687     }
688
689     /* Get the length of the new internal name */
690
691     Info.ExternalName = ExternalName;
692     AcpiNsGetInternalNameLength (&Info);
693
694     /* We need a segment to store the internal  name */
695
696     Info.InternalName = UtGetStringBuffer (Info.Length);
697     if (!Info.InternalName)
698     {
699         return (AE_NO_MEMORY);
700     }
701
702     /* Build the name */
703
704     Status = AcpiNsBuildInternalName (&Info);
705     if (ACPI_FAILURE (Status))
706     {
707         return (Status);
708     }
709
710     *ConvertedName = Info.InternalName;
711     return (AE_OK);
712 }
713
714
715 /*******************************************************************************
716  *
717  * FUNCTION:    UtPadNameWithUnderscores
718  *
719  * PARAMETERS:  NameSeg             - Input nameseg
720  *              PaddedNameSeg       - Output padded nameseg
721  *
722  * RETURN:      Padded nameseg.
723  *
724  * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
725  *              ACPI_NAME.
726  *
727  ******************************************************************************/
728
729 static void
730 UtPadNameWithUnderscores (
731     char                    *NameSeg,
732     char                    *PaddedNameSeg)
733 {
734     UINT32                  i;
735
736
737     for (i = 0; (i < ACPI_NAME_SIZE); i++)
738     {
739         if (*NameSeg)
740         {
741             *PaddedNameSeg = *NameSeg;
742             NameSeg++;
743         }
744         else
745         {
746             *PaddedNameSeg = '_';
747         }
748         PaddedNameSeg++;
749     }
750 }
751
752
753 /*******************************************************************************
754  *
755  * FUNCTION:    UtAttachNameseg
756  *
757  * PARAMETERS:  Op                  - Parent parse node
758  *              Name                - Full ExternalName
759  *
760  * RETURN:      None; Sets the NameSeg field in parent node
761  *
762  * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
763  *              in the NameSeg field of the Op.
764  *
765  ******************************************************************************/
766
767 static void
768 UtAttachNameseg (
769     ACPI_PARSE_OBJECT       *Op,
770     char                    *Name)
771 {
772     char                    *NameSeg;
773     char                    PaddedNameSeg[4];
774
775
776     if (!Name)
777     {
778         return;
779     }
780
781     /* Look for the last dot in the namepath */
782
783     NameSeg = strrchr (Name, '.');
784     if (NameSeg)
785     {
786         /* Found last dot, we have also found the final nameseg */
787
788         NameSeg++;
789         UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
790     }
791     else
792     {
793         /* No dots in the namepath, there is only a single nameseg. */
794         /* Handle prefixes */
795
796         while ((*Name == '\\') || (*Name == '^'))
797         {
798             Name++;
799         }
800
801         /* Remaing string should be one single nameseg */
802
803         UtPadNameWithUnderscores (Name, PaddedNameSeg);
804     }
805
806     strncpy (Op->Asl.NameSeg, PaddedNameSeg, 4);
807 }
808
809
810 /*******************************************************************************
811  *
812  * FUNCTION:    UtAttachNamepathToOwner
813  *
814  * PARAMETERS:  Op                  - Parent parse node
815  *              NameOp              - Node that contains the name
816  *
817  * RETURN:      Sets the ExternalName and Namepath in the parent node
818  *
819  * DESCRIPTION: Store the name in two forms in the parent node: The original
820  *              (external) name, and the internalized name that is used within
821  *              the ACPI namespace manager.
822  *
823  ******************************************************************************/
824
825 void
826 UtAttachNamepathToOwner (
827     ACPI_PARSE_OBJECT       *Op,
828     ACPI_PARSE_OBJECT       *NameOp)
829 {
830     ACPI_STATUS             Status;
831
832
833     /* Full external path */
834
835     Op->Asl.ExternalName = NameOp->Asl.Value.String;
836
837     /* Save the NameOp for possible error reporting later */
838
839     Op->Asl.ParentMethod = (void *) NameOp;
840
841     /* Last nameseg of the path */
842
843     UtAttachNameseg (Op, Op->Asl.ExternalName);
844
845     /* Create internalized path */
846
847     Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
848     if (ACPI_FAILURE (Status))
849     {
850         /* TBD: abort on no memory */
851     }
852 }
853
854
855 /*******************************************************************************
856  *
857  * FUNCTION:    UtDoConstant
858  *
859  * PARAMETERS:  String              - Hex, Octal, or Decimal string
860  *
861  * RETURN:      Converted Integer
862  *
863  * DESCRIPTION: Convert a string to an integer, with error checking.
864  *
865  ******************************************************************************/
866
867 UINT64
868 UtDoConstant (
869     char                    *String)
870 {
871     ACPI_STATUS             Status;
872     UINT64                  Converted;
873     char                    ErrBuf[64];
874
875
876     Status = UtStrtoul64 (String, 0, &Converted);
877     if (ACPI_FAILURE (Status))
878     {
879         sprintf (ErrBuf, "%s %s\n", "Conversion error:",
880             AcpiFormatException (Status));
881         AslCompilererror (ErrBuf);
882     }
883
884     return (Converted);
885 }
886
887
888 /* TBD: use version in ACPI CA main code base? */
889
890 /*******************************************************************************
891  *
892  * FUNCTION:    UtStrtoul64
893  *
894  * PARAMETERS:  String              - Null terminated string
895  *              Terminater          - Where a pointer to the terminating byte
896  *                                    is returned
897  *              Base                - Radix of the string
898  *
899  * RETURN:      Converted value
900  *
901  * DESCRIPTION: Convert a string into an unsigned value.
902  *
903  ******************************************************************************/
904
905 ACPI_STATUS
906 UtStrtoul64 (
907     char                    *String,
908     UINT32                  Base,
909     UINT64                  *RetInteger)
910 {
911     UINT32                  Index;
912     UINT32                  Sign;
913     UINT64                  ReturnValue = 0;
914     ACPI_STATUS             Status = AE_OK;
915
916
917     *RetInteger = 0;
918
919     switch (Base)
920     {
921     case 0:
922     case 8:
923     case 10:
924     case 16:
925         break;
926
927     default:
928         /*
929          * The specified Base parameter is not in the domain of
930          * this function:
931          */
932         return (AE_BAD_PARAMETER);
933     }
934
935     /* Skip over any white space in the buffer: */
936
937     while (isspace ((int) *String) || *String == '\t')
938     {
939         ++String;
940     }
941
942     /*
943      * The buffer may contain an optional plus or minus sign.
944      * If it does, then skip over it but remember what is was:
945      */
946     if (*String == '-')
947     {
948         Sign = NEGATIVE;
949         ++String;
950     }
951     else if (*String == '+')
952     {
953         ++String;
954         Sign = POSITIVE;
955     }
956     else
957     {
958         Sign = POSITIVE;
959     }
960
961     /*
962      * If the input parameter Base is zero, then we need to
963      * determine if it is octal, decimal, or hexadecimal:
964      */
965     if (Base == 0)
966     {
967         if (*String == '0')
968         {
969             if (tolower ((int) *(++String)) == 'x')
970             {
971                 Base = 16;
972                 ++String;
973             }
974             else
975             {
976                 Base = 8;
977             }
978         }
979         else
980         {
981             Base = 10;
982         }
983     }
984
985     /*
986      * For octal and hexadecimal bases, skip over the leading
987      * 0 or 0x, if they are present.
988      */
989     if (Base == 8 && *String == '0')
990     {
991         String++;
992     }
993
994     if (Base == 16 &&
995         *String == '0' &&
996         tolower ((int) *(++String)) == 'x')
997     {
998         String++;
999     }
1000
1001     /* Main loop: convert the string to an unsigned long */
1002
1003     while (*String)
1004     {
1005         if (isdigit ((int) *String))
1006         {
1007             Index = ((UINT8) *String) - '0';
1008         }
1009         else
1010         {
1011             Index = (UINT8) toupper ((int) *String);
1012             if (isupper ((int) Index))
1013             {
1014                 Index = Index - 'A' + 10;
1015             }
1016             else
1017             {
1018                 goto ErrorExit;
1019             }
1020         }
1021
1022         if (Index >= Base)
1023         {
1024             goto ErrorExit;
1025         }
1026
1027         /* Check to see if value is out of range: */
1028
1029         if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
1030                             (UINT64) Base))
1031         {
1032             goto ErrorExit;
1033         }
1034         else
1035         {
1036             ReturnValue *= Base;
1037             ReturnValue += Index;
1038         }
1039
1040         ++String;
1041     }
1042
1043
1044     /* If a minus sign was present, then "the conversion is negated": */
1045
1046     if (Sign == NEGATIVE)
1047     {
1048         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
1049     }
1050
1051     *RetInteger = ReturnValue;
1052     return (Status);
1053
1054
1055 ErrorExit:
1056     switch (Base)
1057     {
1058     case 8:
1059         Status = AE_BAD_OCTAL_CONSTANT;
1060         break;
1061
1062     case 10:
1063         Status = AE_BAD_DECIMAL_CONSTANT;
1064         break;
1065
1066     case 16:
1067         Status = AE_BAD_HEX_CONSTANT;
1068         break;
1069
1070     default:
1071         /* Base validated above */
1072         break;
1073     }
1074
1075     return (Status);
1076 }