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