]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/compiler/aslutils.c
Merge ACPICA 20120816.
[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 #define ACPI_TABLE_HELP_FORMAT  "%8u) %s    %s\n"
109
110 void
111 UtDisplaySupportedTables (
112     void)
113 {
114     ACPI_DMTABLE_DATA       *TableData;
115     UINT32                  i;
116
117
118     printf ("\nACPI tables supported by iASL version %8.8X:\n"
119         "  (Compiler, Disassembler, Template Generator)\n\n",
120         ACPI_CA_VERSION);
121
122     /* Special tables */
123
124     printf ("  Special tables and AML tables:\n");
125     printf (ACPI_TABLE_HELP_FORMAT, 1, ACPI_RSDP_NAME, "Root System Description Pointer");
126     printf (ACPI_TABLE_HELP_FORMAT, 2, ACPI_SIG_FACS, "Firmware ACPI Control Structure");
127     printf (ACPI_TABLE_HELP_FORMAT, 3, ACPI_SIG_DSDT, "Differentiated System Description Table");
128     printf (ACPI_TABLE_HELP_FORMAT, 4, ACPI_SIG_SSDT, "Secondary System Description Table");
129
130     /* All data tables with common table header */
131
132     printf ("\n  Standard ACPI data tables:\n");
133     for (TableData = AcpiDmTableData, i = 5; TableData->Signature; TableData++, i++)
134     {
135         printf (ACPI_TABLE_HELP_FORMAT, i, TableData->Signature, TableData->Name);
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
595     if (!Op)
596     {
597         return NULL;
598     }
599
600     if ((Op->Asl.Value.Integer < LowValue) ||
601         (Op->Asl.Value.Integer > HighValue))
602     {
603         sprintf (MsgBuffer, "0x%X, allowable: 0x%X-0x%X",
604             (UINT32) Op->Asl.Value.Integer, LowValue, HighValue);
605
606         AslError (ASL_ERROR, ASL_MSG_RANGE, Op, MsgBuffer);
607         return (NULL);
608     }
609
610     return (Op);
611 }
612
613
614 /*******************************************************************************
615  *
616  * FUNCTION:    UtGetStringBuffer
617  *
618  * PARAMETERS:  Length              - Size of buffer requested
619  *
620  * RETURN:      Pointer to the buffer. Aborts on allocation failure
621  *
622  * DESCRIPTION: Allocate a string buffer. Bypass the local
623  *              dynamic memory manager for performance reasons (This has a
624  *              major impact on the speed of the compiler.)
625  *
626  ******************************************************************************/
627
628 char *
629 UtGetStringBuffer (
630     UINT32                  Length)
631 {
632     char                    *Buffer;
633
634
635     if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
636     {
637         Gbl_StringCacheNext = UtLocalCalloc (ASL_STRING_CACHE_SIZE + Length);
638         Gbl_StringCacheLast = Gbl_StringCacheNext + ASL_STRING_CACHE_SIZE +
639                                 Length;
640     }
641
642     Buffer = Gbl_StringCacheNext;
643     Gbl_StringCacheNext += Length;
644
645     return (Buffer);
646 }
647
648
649 /*******************************************************************************
650  *
651  * FUNCTION:    UtInternalizeName
652  *
653  * PARAMETERS:  ExternalName        - Name to convert
654  *              ConvertedName       - Where the converted name is returned
655  *
656  * RETURN:      Status
657  *
658  * DESCRIPTION: Convert an external (ASL) name to an internal (AML) name
659  *
660  ******************************************************************************/
661
662 ACPI_STATUS
663 UtInternalizeName (
664     char                    *ExternalName,
665     char                    **ConvertedName)
666 {
667     ACPI_NAMESTRING_INFO    Info;
668     ACPI_STATUS             Status;
669
670
671     if (!ExternalName)
672     {
673         return (AE_OK);
674     }
675
676     /* Get the length of the new internal name */
677
678     Info.ExternalName = ExternalName;
679     AcpiNsGetInternalNameLength (&Info);
680
681     /* We need a segment to store the internal  name */
682
683     Info.InternalName = UtGetStringBuffer (Info.Length);
684     if (!Info.InternalName)
685     {
686         return (AE_NO_MEMORY);
687     }
688
689     /* Build the name */
690
691     Status = AcpiNsBuildInternalName (&Info);
692     if (ACPI_FAILURE (Status))
693     {
694         return (Status);
695     }
696
697     *ConvertedName = Info.InternalName;
698     return (AE_OK);
699 }
700
701
702 /*******************************************************************************
703  *
704  * FUNCTION:    UtPadNameWithUnderscores
705  *
706  * PARAMETERS:  NameSeg             - Input nameseg
707  *              PaddedNameSeg       - Output padded nameseg
708  *
709  * RETURN:      Padded nameseg.
710  *
711  * DESCRIPTION: Pads a NameSeg with underscores if necessary to form a full
712  *              ACPI_NAME.
713  *
714  ******************************************************************************/
715
716 static void
717 UtPadNameWithUnderscores (
718     char                    *NameSeg,
719     char                    *PaddedNameSeg)
720 {
721     UINT32                  i;
722
723
724     for (i = 0; (i < ACPI_NAME_SIZE); i++)
725     {
726         if (*NameSeg)
727         {
728             *PaddedNameSeg = *NameSeg;
729             NameSeg++;
730         }
731         else
732         {
733             *PaddedNameSeg = '_';
734         }
735         PaddedNameSeg++;
736     }
737 }
738
739
740 /*******************************************************************************
741  *
742  * FUNCTION:    UtAttachNameseg
743  *
744  * PARAMETERS:  Op                  - Parent parse node
745  *              Name                - Full ExternalName
746  *
747  * RETURN:      None; Sets the NameSeg field in parent node
748  *
749  * DESCRIPTION: Extract the last nameseg of the ExternalName and store it
750  *              in the NameSeg field of the Op.
751  *
752  ******************************************************************************/
753
754 static void
755 UtAttachNameseg (
756     ACPI_PARSE_OBJECT       *Op,
757     char                    *Name)
758 {
759     char                    *NameSeg;
760     char                    PaddedNameSeg[4];
761
762
763     if (!Name)
764     {
765         return;
766     }
767
768     /* Look for the last dot in the namepath */
769
770     NameSeg = strrchr (Name, '.');
771     if (NameSeg)
772     {
773         /* Found last dot, we have also found the final nameseg */
774
775         NameSeg++;
776         UtPadNameWithUnderscores (NameSeg, PaddedNameSeg);
777     }
778     else
779     {
780         /* No dots in the namepath, there is only a single nameseg. */
781         /* Handle prefixes */
782
783         while ((*Name == '\\') || (*Name == '^'))
784         {
785             Name++;
786         }
787
788         /* Remaing string should be one single nameseg */
789
790         UtPadNameWithUnderscores (Name, PaddedNameSeg);
791     }
792
793     strncpy (Op->Asl.NameSeg, PaddedNameSeg, 4);
794 }
795
796
797 /*******************************************************************************
798  *
799  * FUNCTION:    UtAttachNamepathToOwner
800  *
801  * PARAMETERS:  Op                  - Parent parse node
802  *              NameOp              - Node that contains the name
803  *
804  * RETURN:      Sets the ExternalName and Namepath in the parent node
805  *
806  * DESCRIPTION: Store the name in two forms in the parent node: The original
807  *              (external) name, and the internalized name that is used within
808  *              the ACPI namespace manager.
809  *
810  ******************************************************************************/
811
812 void
813 UtAttachNamepathToOwner (
814     ACPI_PARSE_OBJECT       *Op,
815     ACPI_PARSE_OBJECT       *NameOp)
816 {
817     ACPI_STATUS             Status;
818
819
820     /* Full external path */
821
822     Op->Asl.ExternalName = NameOp->Asl.Value.String;
823
824     /* Save the NameOp for possible error reporting later */
825
826     Op->Asl.ParentMethod = (void *) NameOp;
827
828     /* Last nameseg of the path */
829
830     UtAttachNameseg (Op, Op->Asl.ExternalName);
831
832     /* Create internalized path */
833
834     Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath);
835     if (ACPI_FAILURE (Status))
836     {
837         /* TBD: abort on no memory */
838     }
839 }
840
841
842 /*******************************************************************************
843  *
844  * FUNCTION:    UtDoConstant
845  *
846  * PARAMETERS:  String              - Hex, Octal, or Decimal string
847  *
848  * RETURN:      Converted Integer
849  *
850  * DESCRIPTION: Convert a string to an integer, with error checking.
851  *
852  ******************************************************************************/
853
854 UINT64
855 UtDoConstant (
856     char                    *String)
857 {
858     ACPI_STATUS             Status;
859     UINT64                  Converted;
860     char                    ErrBuf[64];
861
862
863     Status = UtStrtoul64 (String, 0, &Converted);
864     if (ACPI_FAILURE (Status))
865     {
866         sprintf (ErrBuf, "%s %s\n", "Conversion error:",
867             AcpiFormatException (Status));
868         AslCompilererror (ErrBuf);
869     }
870
871     return (Converted);
872 }
873
874
875 /* TBD: use version in ACPI CA main code base? */
876
877 /*******************************************************************************
878  *
879  * FUNCTION:    UtStrtoul64
880  *
881  * PARAMETERS:  String              - Null terminated string
882  *              Terminater          - Where a pointer to the terminating byte
883  *                                    is returned
884  *              Base                - Radix of the string
885  *
886  * RETURN:      Converted value
887  *
888  * DESCRIPTION: Convert a string into an unsigned value.
889  *
890  ******************************************************************************/
891
892 ACPI_STATUS
893 UtStrtoul64 (
894     char                    *String,
895     UINT32                  Base,
896     UINT64                  *RetInteger)
897 {
898     UINT32                  Index;
899     UINT32                  Sign;
900     UINT64                  ReturnValue = 0;
901     ACPI_STATUS             Status = AE_OK;
902
903
904     *RetInteger = 0;
905
906     switch (Base)
907     {
908     case 0:
909     case 8:
910     case 10:
911     case 16:
912         break;
913
914     default:
915         /*
916          * The specified Base parameter is not in the domain of
917          * this function:
918          */
919         return (AE_BAD_PARAMETER);
920     }
921
922     /* Skip over any white space in the buffer: */
923
924     while (isspace ((int) *String) || *String == '\t')
925     {
926         ++String;
927     }
928
929     /*
930      * The buffer may contain an optional plus or minus sign.
931      * If it does, then skip over it but remember what is was:
932      */
933     if (*String == '-')
934     {
935         Sign = NEGATIVE;
936         ++String;
937     }
938     else if (*String == '+')
939     {
940         ++String;
941         Sign = POSITIVE;
942     }
943     else
944     {
945         Sign = POSITIVE;
946     }
947
948     /*
949      * If the input parameter Base is zero, then we need to
950      * determine if it is octal, decimal, or hexadecimal:
951      */
952     if (Base == 0)
953     {
954         if (*String == '0')
955         {
956             if (tolower ((int) *(++String)) == 'x')
957             {
958                 Base = 16;
959                 ++String;
960             }
961             else
962             {
963                 Base = 8;
964             }
965         }
966         else
967         {
968             Base = 10;
969         }
970     }
971
972     /*
973      * For octal and hexadecimal bases, skip over the leading
974      * 0 or 0x, if they are present.
975      */
976     if (Base == 8 && *String == '0')
977     {
978         String++;
979     }
980
981     if (Base == 16 &&
982         *String == '0' &&
983         tolower ((int) *(++String)) == 'x')
984     {
985         String++;
986     }
987
988     /* Main loop: convert the string to an unsigned long */
989
990     while (*String)
991     {
992         if (isdigit ((int) *String))
993         {
994             Index = ((UINT8) *String) - '0';
995         }
996         else
997         {
998             Index = (UINT8) toupper ((int) *String);
999             if (isupper ((int) Index))
1000             {
1001                 Index = Index - 'A' + 10;
1002             }
1003             else
1004             {
1005                 goto ErrorExit;
1006             }
1007         }
1008
1009         if (Index >= Base)
1010         {
1011             goto ErrorExit;
1012         }
1013
1014         /* Check to see if value is out of range: */
1015
1016         if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
1017                             (UINT64) Base))
1018         {
1019             goto ErrorExit;
1020         }
1021         else
1022         {
1023             ReturnValue *= Base;
1024             ReturnValue += Index;
1025         }
1026
1027         ++String;
1028     }
1029
1030
1031     /* If a minus sign was present, then "the conversion is negated": */
1032
1033     if (Sign == NEGATIVE)
1034     {
1035         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
1036     }
1037
1038     *RetInteger = ReturnValue;
1039     return (Status);
1040
1041
1042 ErrorExit:
1043     switch (Base)
1044     {
1045     case 8:
1046         Status = AE_BAD_OCTAL_CONSTANT;
1047         break;
1048
1049     case 10:
1050         Status = AE_BAD_DECIMAL_CONSTANT;
1051         break;
1052
1053     case 16:
1054         Status = AE_BAD_HEX_CONSTANT;
1055         break;
1056
1057     default:
1058         /* Base validated above */
1059         break;
1060     }
1061
1062     return (Status);
1063 }