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