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