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