1 /******************************************************************************* 2 * 3 * Module Name: utmisc - common utility procedures 4 * 5 ******************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 117 #define __UTMISC_C__ 118 119 #include "acpi.h" 120 #include "accommon.h" 121 #include "acnamesp.h" 122 123 124 #define _COMPONENT ACPI_UTILITIES 125 ACPI_MODULE_NAME ("utmisc") 126 127 128 #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP 129 /******************************************************************************* 130 * 131 * FUNCTION: UtConvertBackslashes 132 * 133 * PARAMETERS: Pathname - File pathname string to be converted 134 * 135 * RETURN: Modifies the input Pathname 136 * 137 * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within 138 * the entire input file pathname string. 139 * 140 ******************************************************************************/ 141 142 void 143 UtConvertBackslashes ( 144 char *Pathname) 145 { 146 147 if (!Pathname) 148 { 149 return; 150 } 151 152 while (*Pathname) 153 { 154 if (*Pathname == '\\') 155 { 156 *Pathname = '/'; 157 } 158 159 Pathname++; 160 } 161 } 162 #endif 163 164 165 /******************************************************************************* 166 * 167 * FUNCTION: AcpiUtIsPciRootBridge 168 * 169 * PARAMETERS: Id - The HID/CID in string format 170 * 171 * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge 172 * 173 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. 174 * 175 ******************************************************************************/ 176 177 BOOLEAN 178 AcpiUtIsPciRootBridge ( 179 char *Id) 180 { 181 182 /* 183 * Check if this is a PCI root bridge. 184 * ACPI 3.0+: check for a PCI Express root also. 185 */ 186 if (!(ACPI_STRCMP (Id, 187 PCI_ROOT_HID_STRING)) || 188 189 !(ACPI_STRCMP (Id, 190 PCI_EXPRESS_ROOT_HID_STRING))) 191 { 192 return (TRUE); 193 } 194 195 return (FALSE); 196 } 197 198 199 /******************************************************************************* 200 * 201 * FUNCTION: AcpiUtIsAmlTable 202 * 203 * PARAMETERS: Table - An ACPI table 204 * 205 * RETURN: TRUE if table contains executable AML; FALSE otherwise 206 * 207 * DESCRIPTION: Check ACPI Signature for a table that contains AML code. 208 * Currently, these are DSDT,SSDT,PSDT. All other table types are 209 * data tables that do not contain AML code. 210 * 211 ******************************************************************************/ 212 213 BOOLEAN 214 AcpiUtIsAmlTable ( 215 ACPI_TABLE_HEADER *Table) 216 { 217 218 /* These are the only tables that contain executable AML */ 219 220 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) || 221 ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) || 222 ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT)) 223 { 224 return (TRUE); 225 } 226 227 return (FALSE); 228 } 229 230 231 /******************************************************************************* 232 * 233 * FUNCTION: AcpiUtAllocateOwnerId 234 * 235 * PARAMETERS: OwnerId - Where the new owner ID is returned 236 * 237 * RETURN: Status 238 * 239 * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to 240 * track objects created by the table or method, to be deleted 241 * when the method exits or the table is unloaded. 242 * 243 ******************************************************************************/ 244 245 ACPI_STATUS 246 AcpiUtAllocateOwnerId ( 247 ACPI_OWNER_ID *OwnerId) 248 { 249 UINT32 i; 250 UINT32 j; 251 UINT32 k; 252 ACPI_STATUS Status; 253 254 255 ACPI_FUNCTION_TRACE (UtAllocateOwnerId); 256 257 258 /* Guard against multiple allocations of ID to the same location */ 259 260 if (*OwnerId) 261 { 262 ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId)); 263 return_ACPI_STATUS (AE_ALREADY_EXISTS); 264 } 265 266 /* Mutex for the global ID mask */ 267 268 Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 269 if (ACPI_FAILURE (Status)) 270 { 271 return_ACPI_STATUS (Status); 272 } 273 274 /* 275 * Find a free owner ID, cycle through all possible IDs on repeated 276 * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have 277 * to be scanned twice. 278 */ 279 for (i = 0, j = AcpiGbl_LastOwnerIdIndex; 280 i < (ACPI_NUM_OWNERID_MASKS + 1); 281 i++, j++) 282 { 283 if (j >= ACPI_NUM_OWNERID_MASKS) 284 { 285 j = 0; /* Wraparound to start of mask array */ 286 } 287 288 for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++) 289 { 290 if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX) 291 { 292 /* There are no free IDs in this mask */ 293 294 break; 295 } 296 297 if (!(AcpiGbl_OwnerIdMask[j] & (1 << k))) 298 { 299 /* 300 * Found a free ID. The actual ID is the bit index plus one, 301 * making zero an invalid Owner ID. Save this as the last ID 302 * allocated and update the global ID mask. 303 */ 304 AcpiGbl_OwnerIdMask[j] |= (1 << k); 305 306 AcpiGbl_LastOwnerIdIndex = (UINT8) j; 307 AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1); 308 309 /* 310 * Construct encoded ID from the index and bit position 311 * 312 * Note: Last [j].k (bit 255) is never used and is marked 313 * permanently allocated (prevents +1 overflow) 314 */ 315 *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j)); 316 317 ACPI_DEBUG_PRINT ((ACPI_DB_VALUES, 318 "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId)); 319 goto Exit; 320 } 321 } 322 323 AcpiGbl_NextOwnerIdOffset = 0; 324 } 325 326 /* 327 * All OwnerIds have been allocated. This typically should 328 * not happen since the IDs are reused after deallocation. The IDs are 329 * allocated upon table load (one per table) and method execution, and 330 * they are released when a table is unloaded or a method completes 331 * execution. 332 * 333 * If this error happens, there may be very deep nesting of invoked control 334 * methods, or there may be a bug where the IDs are not released. 335 */ 336 Status = AE_OWNER_ID_LIMIT; 337 ACPI_ERROR ((AE_INFO, 338 "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT")); 339 340 Exit: 341 (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 342 return_ACPI_STATUS (Status); 343 } 344 345 346 /******************************************************************************* 347 * 348 * FUNCTION: AcpiUtReleaseOwnerId 349 * 350 * PARAMETERS: OwnerIdPtr - Pointer to a previously allocated OwnerID 351 * 352 * RETURN: None. No error is returned because we are either exiting a 353 * control method or unloading a table. Either way, we would 354 * ignore any error anyway. 355 * 356 * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255 357 * 358 ******************************************************************************/ 359 360 void 361 AcpiUtReleaseOwnerId ( 362 ACPI_OWNER_ID *OwnerIdPtr) 363 { 364 ACPI_OWNER_ID OwnerId = *OwnerIdPtr; 365 ACPI_STATUS Status; 366 UINT32 Index; 367 UINT32 Bit; 368 369 370 ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId); 371 372 373 /* Always clear the input OwnerId (zero is an invalid ID) */ 374 375 *OwnerIdPtr = 0; 376 377 /* Zero is not a valid OwnerID */ 378 379 if (OwnerId == 0) 380 { 381 ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId)); 382 return_VOID; 383 } 384 385 /* Mutex for the global ID mask */ 386 387 Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 388 if (ACPI_FAILURE (Status)) 389 { 390 return_VOID; 391 } 392 393 /* Normalize the ID to zero */ 394 395 OwnerId--; 396 397 /* Decode ID to index/offset pair */ 398 399 Index = ACPI_DIV_32 (OwnerId); 400 Bit = 1 << ACPI_MOD_32 (OwnerId); 401 402 /* Free the owner ID only if it is valid */ 403 404 if (AcpiGbl_OwnerIdMask[Index] & Bit) 405 { 406 AcpiGbl_OwnerIdMask[Index] ^= Bit; 407 } 408 else 409 { 410 ACPI_ERROR ((AE_INFO, 411 "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1)); 412 } 413 414 (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 415 return_VOID; 416 } 417 418 419 /******************************************************************************* 420 * 421 * FUNCTION: AcpiUtStrupr (strupr) 422 * 423 * PARAMETERS: SrcString - The source string to convert 424 * 425 * RETURN: None 426 * 427 * DESCRIPTION: Convert string to uppercase 428 * 429 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 430 * 431 ******************************************************************************/ 432 433 void 434 AcpiUtStrupr ( 435 char *SrcString) 436 { 437 char *String; 438 439 440 ACPI_FUNCTION_ENTRY (); 441 442 443 if (!SrcString) 444 { 445 return; 446 } 447 448 /* Walk entire string, uppercasing the letters */ 449 450 for (String = SrcString; *String; String++) 451 { 452 *String = (char) ACPI_TOUPPER (*String); 453 } 454 455 return; 456 } 457 458 459 #ifdef ACPI_ASL_COMPILER 460 /******************************************************************************* 461 * 462 * FUNCTION: AcpiUtStrlwr (strlwr) 463 * 464 * PARAMETERS: SrcString - The source string to convert 465 * 466 * RETURN: None 467 * 468 * DESCRIPTION: Convert string to lowercase 469 * 470 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 471 * 472 ******************************************************************************/ 473 474 void 475 AcpiUtStrlwr ( 476 char *SrcString) 477 { 478 char *String; 479 480 481 ACPI_FUNCTION_ENTRY (); 482 483 484 if (!SrcString) 485 { 486 return; 487 } 488 489 /* Walk entire string, lowercasing the letters */ 490 491 for (String = SrcString; *String; String++) 492 { 493 *String = (char) ACPI_TOLOWER (*String); 494 } 495 496 return; 497 } 498 499 500 /****************************************************************************** 501 * 502 * FUNCTION: AcpiUtStricmp 503 * 504 * PARAMETERS: String1 - first string to compare 505 * String2 - second string to compare 506 * 507 * RETURN: int that signifies string relationship. Zero means strings 508 * are equal. 509 * 510 * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare 511 * strings with no case sensitivity) 512 * 513 ******************************************************************************/ 514 515 int 516 AcpiUtStricmp ( 517 char *String1, 518 char *String2) 519 { 520 int c1; 521 int c2; 522 523 524 do 525 { 526 c1 = tolower ((int) *String1); 527 c2 = tolower ((int) *String2); 528 529 String1++; 530 String2++; 531 } 532 while ((c1 == c2) && (c1)); 533 534 return (c1 - c2); 535 } 536 #endif 537 538 539 /******************************************************************************* 540 * 541 * FUNCTION: AcpiUtPrintString 542 * 543 * PARAMETERS: String - Null terminated ASCII string 544 * MaxLength - Maximum output length 545 * 546 * RETURN: None 547 * 548 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 549 * sequences. 550 * 551 ******************************************************************************/ 552 553 void 554 AcpiUtPrintString ( 555 char *String, 556 UINT8 MaxLength) 557 { 558 UINT32 i; 559 560 561 if (!String) 562 { 563 AcpiOsPrintf ("<\"NULL STRING PTR\">"); 564 return; 565 } 566 567 AcpiOsPrintf ("\""); 568 for (i = 0; String[i] && (i < MaxLength); i++) 569 { 570 /* Escape sequences */ 571 572 switch (String[i]) 573 { 574 case 0x07: 575 AcpiOsPrintf ("\\a"); /* BELL */ 576 break; 577 578 case 0x08: 579 AcpiOsPrintf ("\\b"); /* BACKSPACE */ 580 break; 581 582 case 0x0C: 583 AcpiOsPrintf ("\\f"); /* FORMFEED */ 584 break; 585 586 case 0x0A: 587 AcpiOsPrintf ("\\n"); /* LINEFEED */ 588 break; 589 590 case 0x0D: 591 AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/ 592 break; 593 594 case 0x09: 595 AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */ 596 break; 597 598 case 0x0B: 599 AcpiOsPrintf ("\\v"); /* VERTICAL TAB */ 600 break; 601 602 case '\'': /* Single Quote */ 603 case '\"': /* Double Quote */ 604 case '\\': /* Backslash */ 605 AcpiOsPrintf ("\\%c", (int) String[i]); 606 break; 607 608 default: 609 610 /* Check for printable character or hex escape */ 611 612 if (ACPI_IS_PRINT (String[i])) 613 { 614 /* This is a normal character */ 615 616 AcpiOsPrintf ("%c", (int) String[i]); 617 } 618 else 619 { 620 /* All others will be Hex escapes */ 621 622 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]); 623 } 624 break; 625 } 626 } 627 AcpiOsPrintf ("\""); 628 629 if (i == MaxLength && String[i]) 630 { 631 AcpiOsPrintf ("..."); 632 } 633 } 634 635 636 /******************************************************************************* 637 * 638 * FUNCTION: AcpiUtDwordByteSwap 639 * 640 * PARAMETERS: Value - Value to be converted 641 * 642 * RETURN: UINT32 integer with bytes swapped 643 * 644 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 645 * 646 ******************************************************************************/ 647 648 UINT32 649 AcpiUtDwordByteSwap ( 650 UINT32 Value) 651 { 652 union 653 { 654 UINT32 Value; 655 UINT8 Bytes[4]; 656 } Out; 657 union 658 { 659 UINT32 Value; 660 UINT8 Bytes[4]; 661 } In; 662 663 664 ACPI_FUNCTION_ENTRY (); 665 666 667 In.Value = Value; 668 669 Out.Bytes[0] = In.Bytes[3]; 670 Out.Bytes[1] = In.Bytes[2]; 671 Out.Bytes[2] = In.Bytes[1]; 672 Out.Bytes[3] = In.Bytes[0]; 673 674 return (Out.Value); 675 } 676 677 678 /******************************************************************************* 679 * 680 * FUNCTION: AcpiUtSetIntegerWidth 681 * 682 * PARAMETERS: Revision From DSDT header 683 * 684 * RETURN: None 685 * 686 * DESCRIPTION: Set the global integer bit width based upon the revision 687 * of the DSDT. For Revision 1 and 0, Integers are 32 bits. 688 * For Revision 2 and above, Integers are 64 bits. Yes, this 689 * makes a difference. 690 * 691 ******************************************************************************/ 692 693 void 694 AcpiUtSetIntegerWidth ( 695 UINT8 Revision) 696 { 697 698 if (Revision < 2) 699 { 700 /* 32-bit case */ 701 702 AcpiGbl_IntegerBitWidth = 32; 703 AcpiGbl_IntegerNybbleWidth = 8; 704 AcpiGbl_IntegerByteWidth = 4; 705 } 706 else 707 { 708 /* 64-bit case (ACPI 2.0+) */ 709 710 AcpiGbl_IntegerBitWidth = 64; 711 AcpiGbl_IntegerNybbleWidth = 16; 712 AcpiGbl_IntegerByteWidth = 8; 713 } 714 } 715 716 717 #ifdef ACPI_DEBUG_OUTPUT 718 /******************************************************************************* 719 * 720 * FUNCTION: AcpiUtDisplayInitPathname 721 * 722 * PARAMETERS: Type - Object type of the node 723 * ObjHandle - Handle whose pathname will be displayed 724 * Path - Additional path string to be appended. 725 * (NULL if no extra path) 726 * 727 * RETURN: ACPI_STATUS 728 * 729 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY 730 * 731 ******************************************************************************/ 732 733 void 734 AcpiUtDisplayInitPathname ( 735 UINT8 Type, 736 ACPI_NAMESPACE_NODE *ObjHandle, 737 char *Path) 738 { 739 ACPI_STATUS Status; 740 ACPI_BUFFER Buffer; 741 742 743 ACPI_FUNCTION_ENTRY (); 744 745 746 /* Only print the path if the appropriate debug level is enabled */ 747 748 if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES)) 749 { 750 return; 751 } 752 753 /* Get the full pathname to the node */ 754 755 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 756 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 757 if (ACPI_FAILURE (Status)) 758 { 759 return; 760 } 761 762 /* Print what we're doing */ 763 764 switch (Type) 765 { 766 case ACPI_TYPE_METHOD: 767 AcpiOsPrintf ("Executing "); 768 break; 769 770 default: 771 AcpiOsPrintf ("Initializing "); 772 break; 773 } 774 775 /* Print the object type and pathname */ 776 777 AcpiOsPrintf ("%-12s %s", 778 AcpiUtGetTypeName (Type), (char *) Buffer.Pointer); 779 780 /* Extra path is used to append names like _STA, _INI, etc. */ 781 782 if (Path) 783 { 784 AcpiOsPrintf (".%s", Path); 785 } 786 AcpiOsPrintf ("\n"); 787 788 ACPI_FREE (Buffer.Pointer); 789 } 790 #endif 791 792 793 /******************************************************************************* 794 * 795 * FUNCTION: AcpiUtValidAcpiChar 796 * 797 * PARAMETERS: Char - The character to be examined 798 * Position - Byte position (0-3) 799 * 800 * RETURN: TRUE if the character is valid, FALSE otherwise 801 * 802 * DESCRIPTION: Check for a valid ACPI character. Must be one of: 803 * 1) Upper case alpha 804 * 2) numeric 805 * 3) underscore 806 * 807 * We allow a '!' as the last character because of the ASF! table 808 * 809 ******************************************************************************/ 810 811 BOOLEAN 812 AcpiUtValidAcpiChar ( 813 char Character, 814 UINT32 Position) 815 { 816 817 if (!((Character >= 'A' && Character <= 'Z') || 818 (Character >= '0' && Character <= '9') || 819 (Character == '_'))) 820 { 821 /* Allow a '!' in the last position */ 822 823 if (Character == '!' && Position == 3) 824 { 825 return (TRUE); 826 } 827 828 return (FALSE); 829 } 830 831 return (TRUE); 832 } 833 834 835 /******************************************************************************* 836 * 837 * FUNCTION: AcpiUtValidAcpiName 838 * 839 * PARAMETERS: Name - The name to be examined 840 * 841 * RETURN: TRUE if the name is valid, FALSE otherwise 842 * 843 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 844 * 1) Upper case alpha 845 * 2) numeric 846 * 3) underscore 847 * 848 ******************************************************************************/ 849 850 BOOLEAN 851 AcpiUtValidAcpiName ( 852 UINT32 Name) 853 { 854 UINT32 i; 855 856 857 ACPI_FUNCTION_ENTRY (); 858 859 860 for (i = 0; i < ACPI_NAME_SIZE; i++) 861 { 862 if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i)) 863 { 864 return (FALSE); 865 } 866 } 867 868 return (TRUE); 869 } 870 871 872 /******************************************************************************* 873 * 874 * FUNCTION: AcpiUtRepairName 875 * 876 * PARAMETERS: Name - The ACPI name to be repaired 877 * 878 * RETURN: Repaired version of the name 879 * 880 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 881 * return the new name. NOTE: the Name parameter must reside in 882 * read/write memory, cannot be a const. 883 * 884 * An ACPI Name must consist of valid ACPI characters. We will repair the name 885 * if necessary because we don't want to abort because of this, but we want 886 * all namespace names to be printable. A warning message is appropriate. 887 * 888 * This issue came up because there are in fact machines that exhibit 889 * this problem, and we want to be able to enable ACPI support for them, 890 * even though there are a few bad names. 891 * 892 ******************************************************************************/ 893 894 void 895 AcpiUtRepairName ( 896 char *Name) 897 { 898 UINT32 i; 899 BOOLEAN FoundBadChar = FALSE; 900 UINT32 OriginalName; 901 902 903 ACPI_FUNCTION_NAME (UtRepairName); 904 905 906 ACPI_MOVE_NAME (&OriginalName, Name); 907 908 /* Check each character in the name */ 909 910 for (i = 0; i < ACPI_NAME_SIZE; i++) 911 { 912 if (AcpiUtValidAcpiChar (Name[i], i)) 913 { 914 continue; 915 } 916 917 /* 918 * Replace a bad character with something printable, yet technically 919 * still invalid. This prevents any collisions with existing "good" 920 * names in the namespace. 921 */ 922 Name[i] = '*'; 923 FoundBadChar = TRUE; 924 } 925 926 if (FoundBadChar) 927 { 928 /* Report warning only if in strict mode or debug mode */ 929 930 if (!AcpiGbl_EnableInterpreterSlack) 931 { 932 ACPI_WARNING ((AE_INFO, 933 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 934 OriginalName, Name)); 935 } 936 else 937 { 938 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 939 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", 940 OriginalName, Name)); 941 } 942 } 943 } 944 945 946 /******************************************************************************* 947 * 948 * FUNCTION: AcpiUtStrtoul64 949 * 950 * PARAMETERS: String - Null terminated string 951 * Base - Radix of the string: 16 or ACPI_ANY_BASE; 952 * ACPI_ANY_BASE means 'in behalf of ToInteger' 953 * RetInteger - Where the converted integer is returned 954 * 955 * RETURN: Status and Converted value 956 * 957 * DESCRIPTION: Convert a string into an unsigned value. Performs either a 958 * 32-bit or 64-bit conversion, depending on the current mode 959 * of the interpreter. 960 * NOTE: Does not support Octal strings, not needed. 961 * 962 ******************************************************************************/ 963 964 ACPI_STATUS 965 AcpiUtStrtoul64 ( 966 char *String, 967 UINT32 Base, 968 UINT64 *RetInteger) 969 { 970 UINT32 ThisDigit = 0; 971 UINT64 ReturnValue = 0; 972 UINT64 Quotient; 973 UINT64 Dividend; 974 UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE); 975 UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4); 976 UINT8 ValidDigits = 0; 977 UINT8 SignOf0x = 0; 978 UINT8 Term = 0; 979 980 981 ACPI_FUNCTION_TRACE_STR (UtStroul64, String); 982 983 984 switch (Base) 985 { 986 case ACPI_ANY_BASE: 987 case 16: 988 break; 989 990 default: 991 /* Invalid Base */ 992 return_ACPI_STATUS (AE_BAD_PARAMETER); 993 } 994 995 if (!String) 996 { 997 goto ErrorExit; 998 } 999 1000 /* Skip over any white space in the buffer */ 1001 1002 while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t')) 1003 { 1004 String++; 1005 } 1006 1007 if (ToIntegerOp) 1008 { 1009 /* 1010 * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 1011 * We need to determine if it is decimal or hexadecimal. 1012 */ 1013 if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x')) 1014 { 1015 SignOf0x = 1; 1016 Base = 16; 1017 1018 /* Skip over the leading '0x' */ 1019 String += 2; 1020 } 1021 else 1022 { 1023 Base = 10; 1024 } 1025 } 1026 1027 /* Any string left? Check that '0x' is not followed by white space. */ 1028 1029 if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t') 1030 { 1031 if (ToIntegerOp) 1032 { 1033 goto ErrorExit; 1034 } 1035 else 1036 { 1037 goto AllDone; 1038 } 1039 } 1040 1041 /* 1042 * Perform a 32-bit or 64-bit conversion, depending upon the current 1043 * execution mode of the interpreter 1044 */ 1045 Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 1046 1047 /* Main loop: convert the string to a 32- or 64-bit integer */ 1048 1049 while (*String) 1050 { 1051 if (ACPI_IS_DIGIT (*String)) 1052 { 1053 /* Convert ASCII 0-9 to Decimal value */ 1054 1055 ThisDigit = ((UINT8) *String) - '0'; 1056 } 1057 else if (Base == 10) 1058 { 1059 /* Digit is out of range; possible in ToInteger case only */ 1060 1061 Term = 1; 1062 } 1063 else 1064 { 1065 ThisDigit = (UINT8) ACPI_TOUPPER (*String); 1066 if (ACPI_IS_XDIGIT ((char) ThisDigit)) 1067 { 1068 /* Convert ASCII Hex char to value */ 1069 1070 ThisDigit = ThisDigit - 'A' + 10; 1071 } 1072 else 1073 { 1074 Term = 1; 1075 } 1076 } 1077 1078 if (Term) 1079 { 1080 if (ToIntegerOp) 1081 { 1082 goto ErrorExit; 1083 } 1084 else 1085 { 1086 break; 1087 } 1088 } 1089 else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 1090 { 1091 /* Skip zeros */ 1092 String++; 1093 continue; 1094 } 1095 1096 ValidDigits++; 1097 1098 if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32))) 1099 { 1100 /* 1101 * This is ToInteger operation case. 1102 * No any restrictions for string-to-integer conversion, 1103 * see ACPI spec. 1104 */ 1105 goto ErrorExit; 1106 } 1107 1108 /* Divide the digit into the correct position */ 1109 1110 (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit), 1111 Base, &Quotient, NULL); 1112 1113 if (ReturnValue > Quotient) 1114 { 1115 if (ToIntegerOp) 1116 { 1117 goto ErrorExit; 1118 } 1119 else 1120 { 1121 break; 1122 } 1123 } 1124 1125 ReturnValue *= Base; 1126 ReturnValue += ThisDigit; 1127 String++; 1128 } 1129 1130 /* All done, normal exit */ 1131 1132 AllDone: 1133 1134 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 1135 ACPI_FORMAT_UINT64 (ReturnValue))); 1136 1137 *RetInteger = ReturnValue; 1138 return_ACPI_STATUS (AE_OK); 1139 1140 1141 ErrorExit: 1142 /* Base was set/validated above */ 1143 1144 if (Base == 10) 1145 { 1146 return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 1147 } 1148 else 1149 { 1150 return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 1151 } 1152 } 1153 1154 1155 /******************************************************************************* 1156 * 1157 * FUNCTION: AcpiUtCreateUpdateStateAndPush 1158 * 1159 * PARAMETERS: Object - Object to be added to the new state 1160 * Action - Increment/Decrement 1161 * StateList - List the state will be added to 1162 * 1163 * RETURN: Status 1164 * 1165 * DESCRIPTION: Create a new state and push it 1166 * 1167 ******************************************************************************/ 1168 1169 ACPI_STATUS 1170 AcpiUtCreateUpdateStateAndPush ( 1171 ACPI_OPERAND_OBJECT *Object, 1172 UINT16 Action, 1173 ACPI_GENERIC_STATE **StateList) 1174 { 1175 ACPI_GENERIC_STATE *State; 1176 1177 1178 ACPI_FUNCTION_ENTRY (); 1179 1180 1181 /* Ignore null objects; these are expected */ 1182 1183 if (!Object) 1184 { 1185 return (AE_OK); 1186 } 1187 1188 State = AcpiUtCreateUpdateState (Object, Action); 1189 if (!State) 1190 { 1191 return (AE_NO_MEMORY); 1192 } 1193 1194 AcpiUtPushGenericState (StateList, State); 1195 return (AE_OK); 1196 } 1197 1198 1199 /******************************************************************************* 1200 * 1201 * FUNCTION: AcpiUtWalkPackageTree 1202 * 1203 * PARAMETERS: SourceObject - The package to walk 1204 * TargetObject - Target object (if package is being copied) 1205 * WalkCallback - Called once for each package element 1206 * Context - Passed to the callback function 1207 * 1208 * RETURN: Status 1209 * 1210 * DESCRIPTION: Walk through a package 1211 * 1212 ******************************************************************************/ 1213 1214 ACPI_STATUS 1215 AcpiUtWalkPackageTree ( 1216 ACPI_OPERAND_OBJECT *SourceObject, 1217 void *TargetObject, 1218 ACPI_PKG_CALLBACK WalkCallback, 1219 void *Context) 1220 { 1221 ACPI_STATUS Status = AE_OK; 1222 ACPI_GENERIC_STATE *StateList = NULL; 1223 ACPI_GENERIC_STATE *State; 1224 UINT32 ThisIndex; 1225 ACPI_OPERAND_OBJECT *ThisSourceObj; 1226 1227 1228 ACPI_FUNCTION_TRACE (UtWalkPackageTree); 1229 1230 1231 State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 1232 if (!State) 1233 { 1234 return_ACPI_STATUS (AE_NO_MEMORY); 1235 } 1236 1237 while (State) 1238 { 1239 /* Get one element of the package */ 1240 1241 ThisIndex = State->Pkg.Index; 1242 ThisSourceObj = (ACPI_OPERAND_OBJECT *) 1243 State->Pkg.SourceObject->Package.Elements[ThisIndex]; 1244 1245 /* 1246 * Check for: 1247 * 1) An uninitialized package element. It is completely 1248 * legal to declare a package and leave it uninitialized 1249 * 2) Not an internal object - can be a namespace node instead 1250 * 3) Any type other than a package. Packages are handled in else 1251 * case below. 1252 */ 1253 if ((!ThisSourceObj) || 1254 (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) || 1255 (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE)) 1256 { 1257 Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 1258 State, Context); 1259 if (ACPI_FAILURE (Status)) 1260 { 1261 return_ACPI_STATUS (Status); 1262 } 1263 1264 State->Pkg.Index++; 1265 while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count) 1266 { 1267 /* 1268 * We've handled all of the objects at this level, This means 1269 * that we have just completed a package. That package may 1270 * have contained one or more packages itself. 1271 * 1272 * Delete this state and pop the previous state (package). 1273 */ 1274 AcpiUtDeleteGenericState (State); 1275 State = AcpiUtPopGenericState (&StateList); 1276 1277 /* Finished when there are no more states */ 1278 1279 if (!State) 1280 { 1281 /* 1282 * We have handled all of the objects in the top level 1283 * package just add the length of the package objects 1284 * and exit 1285 */ 1286 return_ACPI_STATUS (AE_OK); 1287 } 1288 1289 /* 1290 * Go back up a level and move the index past the just 1291 * completed package object. 1292 */ 1293 State->Pkg.Index++; 1294 } 1295 } 1296 else 1297 { 1298 /* This is a subobject of type package */ 1299 1300 Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, 1301 State, Context); 1302 if (ACPI_FAILURE (Status)) 1303 { 1304 return_ACPI_STATUS (Status); 1305 } 1306 1307 /* 1308 * Push the current state and create a new one 1309 * The callback above returned a new target package object. 1310 */ 1311 AcpiUtPushGenericState (&StateList, State); 1312 State = AcpiUtCreatePkgState (ThisSourceObj, 1313 State->Pkg.ThisTargetObj, 0); 1314 if (!State) 1315 { 1316 /* Free any stacked Update State objects */ 1317 1318 while (StateList) 1319 { 1320 State = AcpiUtPopGenericState (&StateList); 1321 AcpiUtDeleteGenericState (State); 1322 } 1323 return_ACPI_STATUS (AE_NO_MEMORY); 1324 } 1325 } 1326 } 1327 1328 /* We should never get here */ 1329 1330 return_ACPI_STATUS (AE_AML_INTERNAL); 1331 } 1332