1 2 /****************************************************************************** 3 * 4 * Module Name: aslutils -- compiler utilities 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2011, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 46 #include <contrib/dev/acpica/compiler/aslcompiler.h> 47 #include "aslcompiler.y.h" 48 #include <contrib/dev/acpica/include/acdisasm.h> 49 #include <contrib/dev/acpica/include/acnamesp.h> 50 #include <contrib/dev/acpica/include/amlcode.h> 51 #include <contrib/dev/acpica/include/acapps.h> 52 53 #define _COMPONENT ACPI_COMPILER 54 ACPI_MODULE_NAME ("aslutils") 55 56 #ifdef _USE_BERKELEY_YACC 57 extern const char * const AslCompilername[]; 58 static const char * const *yytname = &AslCompilername[254]; 59 #else 60 extern const char * const yytname[]; 61 #endif 62 63 char AslHexLookup[] = 64 { 65 '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' 66 }; 67 68 69 /* Local prototypes */ 70 71 static ACPI_STATUS 72 UtStrtoul64 ( 73 char *String, 74 UINT32 Base, 75 UINT64 *RetInteger); 76 77 static void 78 UtPadNameWithUnderscores ( 79 char *NameSeg, 80 char *PaddedNameSeg); 81 82 static void 83 UtAttachNameseg ( 84 ACPI_PARSE_OBJECT *Op, 85 char *Name); 86 87 88 /******************************************************************************* 89 * 90 * FUNCTION: UtDisplaySupportedTables 91 * 92 * PARAMETERS: None 93 * 94 * RETURN: None 95 * 96 * DESCRIPTION: Print all supported ACPI table names. 97 * 98 ******************************************************************************/ 99 100 void 101 UtDisplaySupportedTables ( 102 void) 103 { 104 ACPI_DMTABLE_DATA *TableData; 105 UINT32 i = 6; 106 107 108 printf ("\nACPI tables supported by iASL subsystems in " 109 "version %8.8X:\n" 110 " ASL and Data Table compilers\n" 111 " AML and Data Table disassemblers\n" 112 " ACPI table template generator\n\n", ACPI_CA_VERSION); 113 114 /* Special tables */ 115 116 printf ("%8u) %s %s\n", 1, ACPI_SIG_DSDT, "Differentiated System Description Table"); 117 printf ("%8u) %s %s\n", 2, ACPI_SIG_SSDT, "Secondary System Description Table"); 118 printf ("%8u) %s %s\n", 3, ACPI_SIG_FADT, "Fixed ACPI Description Table (FADT)"); 119 printf ("%8u) %s %s\n", 4, ACPI_SIG_FACS, "Firmware ACPI Control Structure"); 120 printf ("%8u) %s %s\n", 5, ACPI_RSDP_NAME, "Root System Description Pointer"); 121 122 /* All data tables with common table header */ 123 124 for (TableData = AcpiDmTableData; TableData->Signature; TableData++) 125 { 126 printf ("%8u) %s %s\n", i, TableData->Signature, TableData->Name); 127 i++; 128 } 129 } 130 131 132 /******************************************************************************* 133 * 134 * FUNCTION: AcpiPsDisplayConstantOpcodes 135 * 136 * PARAMETERS: None 137 * 138 * RETURN: None 139 * 140 * DESCRIPTION: Print AML opcodes that can be used in constant expressions. 141 * 142 ******************************************************************************/ 143 144 void 145 UtDisplayConstantOpcodes ( 146 void) 147 { 148 UINT32 i; 149 150 151 printf ("Constant expression opcode information\n\n"); 152 153 for (i = 0; i < sizeof (AcpiGbl_AmlOpInfo) / sizeof (ACPI_OPCODE_INFO); i++) 154 { 155 if (AcpiGbl_AmlOpInfo[i].Flags & AML_CONSTANT) 156 { 157 printf ("%s\n", AcpiGbl_AmlOpInfo[i].Name); 158 } 159 } 160 } 161 162 163 /******************************************************************************* 164 * 165 * FUNCTION: UtLocalCalloc 166 * 167 * PARAMETERS: Size - Bytes to be allocated 168 * 169 * RETURN: Pointer to the allocated memory. Guaranteed to be valid. 170 * 171 * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an 172 * allocation failure, on the assumption that nothing more can be 173 * accomplished. 174 * 175 ******************************************************************************/ 176 177 void * 178 UtLocalCalloc ( 179 UINT32 Size) 180 { 181 void *Allocated; 182 183 184 Allocated = ACPI_ALLOCATE_ZEROED (Size); 185 if (!Allocated) 186 { 187 AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION, 188 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber, 189 Gbl_InputByteCount, Gbl_CurrentColumn, 190 Gbl_Files[ASL_FILE_INPUT].Filename, NULL); 191 192 CmCleanupAndExit (); 193 exit (1); 194 } 195 196 TotalAllocations++; 197 TotalAllocated += Size; 198 return (Allocated); 199 } 200 201 202 /******************************************************************************* 203 * 204 * FUNCTION: UtBeginEvent 205 * 206 * PARAMETERS: Name - Ascii name of this event 207 * 208 * RETURN: Event - Event number (integer index) 209 * 210 * DESCRIPTION: Saves the current time with this event 211 * 212 ******************************************************************************/ 213 214 UINT8 215 UtBeginEvent ( 216 char *Name) 217 { 218 219 if (AslGbl_NextEvent >= ASL_NUM_EVENTS) 220 { 221 AcpiOsPrintf ("Ran out of compiler event structs!\n"); 222 return (AslGbl_NextEvent); 223 } 224 225 /* Init event with current (start) time */ 226 227 AslGbl_Events[AslGbl_NextEvent].StartTime = AcpiOsGetTimer (); 228 AslGbl_Events[AslGbl_NextEvent].EventName = Name; 229 AslGbl_Events[AslGbl_NextEvent].Valid = TRUE; 230 231 return (AslGbl_NextEvent++); 232 } 233 234 235 /******************************************************************************* 236 * 237 * FUNCTION: UtEndEvent 238 * 239 * PARAMETERS: Event - Event number (integer index) 240 * 241 * RETURN: None 242 * 243 * DESCRIPTION: Saves the current time (end time) with this event 244 * 245 ******************************************************************************/ 246 247 void 248 UtEndEvent ( 249 UINT8 Event) 250 { 251 252 if (Event >= ASL_NUM_EVENTS) 253 { 254 return; 255 } 256 257 /* Insert end time for event */ 258 259 AslGbl_Events[Event].EndTime = AcpiOsGetTimer (); 260 } 261 262 263 /******************************************************************************* 264 * 265 * FUNCTION: UtHexCharToValue 266 * 267 * PARAMETERS: HexChar - Hex character in Ascii 268 * 269 * RETURN: The binary value of the hex character 270 * 271 * DESCRIPTION: Perform ascii-to-hex translation 272 * 273 ******************************************************************************/ 274 275 UINT8 276 UtHexCharToValue ( 277 int HexChar) 278 { 279 280 if (HexChar <= 0x39) 281 { 282 return ((UINT8) (HexChar - 0x30)); 283 } 284 285 if (HexChar <= 0x46) 286 { 287 return ((UINT8) (HexChar - 0x37)); 288 } 289 290 return ((UINT8) (HexChar - 0x57)); 291 } 292 293 294 /******************************************************************************* 295 * 296 * FUNCTION: UtConvertByteToHex 297 * 298 * PARAMETERS: RawByte - Binary data 299 * Buffer - Pointer to where the hex bytes will be stored 300 * 301 * RETURN: Ascii hex byte is stored in Buffer. 302 * 303 * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed 304 * with "0x" 305 * 306 ******************************************************************************/ 307 308 void 309 UtConvertByteToHex ( 310 UINT8 RawByte, 311 UINT8 *Buffer) 312 { 313 314 Buffer[0] = '0'; 315 Buffer[1] = 'x'; 316 317 Buffer[2] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF]; 318 Buffer[3] = (UINT8) AslHexLookup[RawByte & 0xF]; 319 } 320 321 322 /******************************************************************************* 323 * 324 * FUNCTION: UtConvertByteToAsmHex 325 * 326 * PARAMETERS: RawByte - Binary data 327 * Buffer - Pointer to where the hex bytes will be stored 328 * 329 * RETURN: Ascii hex byte is stored in Buffer. 330 * 331 * DESCRIPTION: Perform hex-to-ascii translation. The return data is prefixed 332 * with "0x" 333 * 334 ******************************************************************************/ 335 336 void 337 UtConvertByteToAsmHex ( 338 UINT8 RawByte, 339 UINT8 *Buffer) 340 { 341 342 Buffer[0] = '0'; 343 Buffer[1] = (UINT8) AslHexLookup[(RawByte >> 4) & 0xF]; 344 Buffer[2] = (UINT8) AslHexLookup[RawByte & 0xF]; 345 Buffer[3] = 'h'; 346 } 347 348 349 /******************************************************************************* 350 * 351 * FUNCTION: DbgPrint 352 * 353 * PARAMETERS: Type - Type of output 354 * Fmt - Printf format string 355 * ... - variable printf list 356 * 357 * RETURN: None 358 * 359 * DESCRIPTION: Conditional print statement. Prints to stderr only if the 360 * debug flag is set. 361 * 362 ******************************************************************************/ 363 364 void 365 DbgPrint ( 366 UINT32 Type, 367 char *Fmt, 368 ...) 369 { 370 va_list Args; 371 372 373 va_start (Args, Fmt); 374 375 if (!Gbl_DebugFlag) 376 { 377 return; 378 } 379 380 if ((Type == ASL_PARSE_OUTPUT) && 381 (!(AslCompilerdebug))) 382 { 383 return; 384 } 385 386 (void) vfprintf (stderr, Fmt, Args); 387 va_end (Args); 388 return; 389 } 390 391 392 /******************************************************************************* 393 * 394 * FUNCTION: UtPrintFormattedName 395 * 396 * PARAMETERS: ParseOpcode - Parser keyword ID 397 * Level - Indentation level 398 * 399 * RETURN: None 400 * 401 * DESCRIPTION: Print the ascii name of the parse opcode. 402 * 403 ******************************************************************************/ 404 405 #define TEXT_OFFSET 10 406 407 void 408 UtPrintFormattedName ( 409 UINT16 ParseOpcode, 410 UINT32 Level) 411 { 412 413 if (Level) 414 { 415 DbgPrint (ASL_TREE_OUTPUT, 416 "%*s", (3 * Level), " "); 417 } 418 DbgPrint (ASL_TREE_OUTPUT, 419 " %-20.20s", UtGetOpName (ParseOpcode)); 420 421 if (Level < TEXT_OFFSET) 422 { 423 DbgPrint (ASL_TREE_OUTPUT, 424 "%*s", (TEXT_OFFSET - Level) * 3, " "); 425 } 426 } 427 428 429 /******************************************************************************* 430 * 431 * FUNCTION: UtSetParseOpName 432 * 433 * PARAMETERS: Op 434 * 435 * RETURN: None 436 * 437 * DESCRIPTION: Insert the ascii name of the parse opcode 438 * 439 ******************************************************************************/ 440 441 void 442 UtSetParseOpName ( 443 ACPI_PARSE_OBJECT *Op) 444 { 445 446 strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode), 447 ACPI_MAX_PARSEOP_NAME); 448 } 449 450 451 /******************************************************************************* 452 * 453 * FUNCTION: UtGetOpName 454 * 455 * PARAMETERS: ParseOpcode - Parser keyword ID 456 * 457 * RETURN: Pointer to the opcode name 458 * 459 * DESCRIPTION: Get the ascii name of the parse opcode 460 * 461 ******************************************************************************/ 462 463 char * 464 UtGetOpName ( 465 UINT32 ParseOpcode) 466 { 467 468 /* 469 * First entries (ASL_YYTNAME_START) in yytname are special reserved names. 470 * Ignore first 8 characters of the name 471 */ 472 return ((char *) yytname 473 [(ParseOpcode - ASL_FIRST_PARSE_OPCODE) + ASL_YYTNAME_START] + 8); 474 } 475 476 477 /******************************************************************************* 478 * 479 * FUNCTION: UtDisplaySummary 480 * 481 * PARAMETERS: FileID - ID of outpout file 482 * 483 * RETURN: None 484 * 485 * DESCRIPTION: Display compilation statistics 486 * 487 ******************************************************************************/ 488 489 void 490 UtDisplaySummary ( 491 UINT32 FileId) 492 { 493 494 if (FileId != ASL_FILE_STDOUT) 495 { 496 /* Compiler name and version number */ 497 498 FlPrintFile (FileId, "%s version %X%s\n", 499 ASL_COMPILER_NAME, (UINT32) ACPI_CA_VERSION, ACPI_WIDTH); 500 } 501 502 if (Gbl_FileType == ASL_INPUT_TYPE_ASCII_DATA) 503 { 504 FlPrintFile (FileId, 505 "Table Input: %s - %u lines, %u bytes, %u fields\n", 506 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, 507 Gbl_InputByteCount, Gbl_InputFieldCount); 508 509 if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors)) 510 { 511 FlPrintFile (FileId, 512 "Binary Output: %s - %u bytes\n\n", 513 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength); 514 } 515 } 516 else 517 { 518 /* Input/Output summary */ 519 520 FlPrintFile (FileId, 521 "ASL Input: %s - %u lines, %u bytes, %u keywords\n", 522 Gbl_Files[ASL_FILE_INPUT].Filename, Gbl_CurrentLineNumber, 523 Gbl_InputByteCount, TotalKeywords); 524 525 /* AML summary */ 526 527 if ((Gbl_ExceptionCount[ASL_ERROR] == 0) || (Gbl_IgnoreErrors)) 528 { 529 FlPrintFile (FileId, 530 "AML Output: %s - %u bytes, %u named objects, %u executable opcodes\n\n", 531 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength, 532 TotalNamedObjects, TotalExecutableOpcodes); 533 } 534 } 535 536 /* Error summary */ 537 538 FlPrintFile (FileId, 539 "Compilation complete. %u Errors, %u Warnings, %u Remarks", 540 Gbl_ExceptionCount[ASL_ERROR], 541 Gbl_ExceptionCount[ASL_WARNING] + 542 Gbl_ExceptionCount[ASL_WARNING2] + 543 Gbl_ExceptionCount[ASL_WARNING3], 544 Gbl_ExceptionCount[ASL_REMARK]); 545 546 if (Gbl_FileType != ASL_INPUT_TYPE_ASCII_DATA) 547 { 548 FlPrintFile (FileId, 549 ", %u Optimizations", Gbl_ExceptionCount[ASL_OPTIMIZATION]); 550 } 551 552 FlPrintFile (FileId, "\n"); 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 UINT64 850 UtDoConstant ( 851 char *String) 852 { 853 ACPI_STATUS Status; 854 UINT64 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 UINT64 *RetInteger) 892 { 893 UINT32 Index; 894 UINT32 Sign; 895 UINT64 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 ((int) *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 ((int) *(++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 ((int) *(++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 ((int) *String)) 988 { 989 Index = ((UINT8) *String) - '0'; 990 } 991 else 992 { 993 Index = (UINT8) toupper ((int) *String); 994 if (isupper ((int) 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_UINT64_MAX - (UINT64) Index) / 1012 (UINT64) 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