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