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