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