1 /****************************************************************************** 2 * 3 * Module Name: aslutils -- compiler utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 (ACPI_IS_ROOT_PREFIX (*Name) || 830 ACPI_IS_PARENT_PREFIX (*Name)) 831 { 832 Name++; 833 } 834 835 /* Remaining string should be one single nameseg */ 836 837 UtPadNameWithUnderscores (Name, PaddedNameSeg); 838 } 839 840 ACPI_MOVE_NAME (Op->Asl.NameSeg, PaddedNameSeg); 841 } 842 843 844 /******************************************************************************* 845 * 846 * FUNCTION: UtAttachNamepathToOwner 847 * 848 * PARAMETERS: Op - Parent parse node 849 * NameOp - Node that contains the name 850 * 851 * RETURN: Sets the ExternalName and Namepath in the parent node 852 * 853 * DESCRIPTION: Store the name in two forms in the parent node: The original 854 * (external) name, and the internalized name that is used within 855 * the ACPI namespace manager. 856 * 857 ******************************************************************************/ 858 859 void 860 UtAttachNamepathToOwner ( 861 ACPI_PARSE_OBJECT *Op, 862 ACPI_PARSE_OBJECT *NameOp) 863 { 864 ACPI_STATUS Status; 865 866 867 /* Full external path */ 868 869 Op->Asl.ExternalName = NameOp->Asl.Value.String; 870 871 /* Save the NameOp for possible error reporting later */ 872 873 Op->Asl.ParentMethod = (void *) NameOp; 874 875 /* Last nameseg of the path */ 876 877 UtAttachNameseg (Op, Op->Asl.ExternalName); 878 879 /* Create internalized path */ 880 881 Status = UtInternalizeName (NameOp->Asl.Value.String, &Op->Asl.Namepath); 882 if (ACPI_FAILURE (Status)) 883 { 884 /* TBD: abort on no memory */ 885 } 886 } 887 888 889 /******************************************************************************* 890 * 891 * FUNCTION: UtDoConstant 892 * 893 * PARAMETERS: String - Hex, Octal, or Decimal string 894 * 895 * RETURN: Converted Integer 896 * 897 * DESCRIPTION: Convert a string to an integer, with error checking. 898 * 899 ******************************************************************************/ 900 901 UINT64 902 UtDoConstant ( 903 char *String) 904 { 905 ACPI_STATUS Status; 906 UINT64 Converted; 907 char ErrBuf[64]; 908 909 910 Status = UtStrtoul64 (String, 0, &Converted); 911 if (ACPI_FAILURE (Status)) 912 { 913 sprintf (ErrBuf, "%s %s\n", "Conversion error:", 914 AcpiFormatException (Status)); 915 AslCompilererror (ErrBuf); 916 } 917 918 return (Converted); 919 } 920 921 922 /* TBD: use version in ACPI CA main code base? */ 923 924 /******************************************************************************* 925 * 926 * FUNCTION: UtStrtoul64 927 * 928 * PARAMETERS: String - Null terminated string 929 * Terminater - Where a pointer to the terminating byte 930 * is returned 931 * Base - Radix of the string 932 * 933 * RETURN: Converted value 934 * 935 * DESCRIPTION: Convert a string into an unsigned value. 936 * 937 ******************************************************************************/ 938 939 ACPI_STATUS 940 UtStrtoul64 ( 941 char *String, 942 UINT32 Base, 943 UINT64 *RetInteger) 944 { 945 UINT32 Index; 946 UINT32 Sign; 947 UINT64 ReturnValue = 0; 948 ACPI_STATUS Status = AE_OK; 949 950 951 *RetInteger = 0; 952 953 switch (Base) 954 { 955 case 0: 956 case 8: 957 case 10: 958 case 16: 959 break; 960 961 default: 962 /* 963 * The specified Base parameter is not in the domain of 964 * this function: 965 */ 966 return (AE_BAD_PARAMETER); 967 } 968 969 /* Skip over any white space in the buffer: */ 970 971 while (isspace ((int) *String) || *String == '\t') 972 { 973 ++String; 974 } 975 976 /* 977 * The buffer may contain an optional plus or minus sign. 978 * If it does, then skip over it but remember what is was: 979 */ 980 if (*String == '-') 981 { 982 Sign = NEGATIVE; 983 ++String; 984 } 985 else if (*String == '+') 986 { 987 ++String; 988 Sign = POSITIVE; 989 } 990 else 991 { 992 Sign = POSITIVE; 993 } 994 995 /* 996 * If the input parameter Base is zero, then we need to 997 * determine if it is octal, decimal, or hexadecimal: 998 */ 999 if (Base == 0) 1000 { 1001 if (*String == '0') 1002 { 1003 if (tolower ((int) *(++String)) == 'x') 1004 { 1005 Base = 16; 1006 ++String; 1007 } 1008 else 1009 { 1010 Base = 8; 1011 } 1012 } 1013 else 1014 { 1015 Base = 10; 1016 } 1017 } 1018 1019 /* 1020 * For octal and hexadecimal bases, skip over the leading 1021 * 0 or 0x, if they are present. 1022 */ 1023 if (Base == 8 && *String == '0') 1024 { 1025 String++; 1026 } 1027 1028 if (Base == 16 && 1029 *String == '0' && 1030 tolower ((int) *(++String)) == 'x') 1031 { 1032 String++; 1033 } 1034 1035 /* Main loop: convert the string to an unsigned long */ 1036 1037 while (*String) 1038 { 1039 if (isdigit ((int) *String)) 1040 { 1041 Index = ((UINT8) *String) - '0'; 1042 } 1043 else 1044 { 1045 Index = (UINT8) toupper ((int) *String); 1046 if (isupper ((int) Index)) 1047 { 1048 Index = Index - 'A' + 10; 1049 } 1050 else 1051 { 1052 goto ErrorExit; 1053 } 1054 } 1055 1056 if (Index >= Base) 1057 { 1058 goto ErrorExit; 1059 } 1060 1061 /* Check to see if value is out of range: */ 1062 1063 if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / 1064 (UINT64) Base)) 1065 { 1066 goto ErrorExit; 1067 } 1068 else 1069 { 1070 ReturnValue *= Base; 1071 ReturnValue += Index; 1072 } 1073 1074 ++String; 1075 } 1076 1077 1078 /* If a minus sign was present, then "the conversion is negated": */ 1079 1080 if (Sign == NEGATIVE) 1081 { 1082 ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; 1083 } 1084 1085 *RetInteger = ReturnValue; 1086 return (Status); 1087 1088 1089 ErrorExit: 1090 switch (Base) 1091 { 1092 case 8: 1093 Status = AE_BAD_OCTAL_CONSTANT; 1094 break; 1095 1096 case 10: 1097 Status = AE_BAD_DECIMAL_CONSTANT; 1098 break; 1099 1100 case 16: 1101 Status = AE_BAD_HEX_CONSTANT; 1102 break; 1103 1104 default: 1105 /* Base validated above */ 1106 break; 1107 } 1108 1109 return (Status); 1110 } 1111