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 1132