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