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