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