]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/compiler/aslutils.c
Merge ACPICA 20120320.
[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:    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