Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenutmisc.c
Go to the documentation of this file.
00001 /******************************************************************************* 00002 * 00003 * Module Name: utmisc - common utility procedures 00004 * 00005 ******************************************************************************/ 00006 00007 /****************************************************************************** 00008 * 00009 * 1. Copyright Notice 00010 * 00011 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00012 * All rights reserved. 00013 * 00014 * 2. License 00015 * 00016 * 2.1. This is your license from Intel Corp. under its intellectual property 00017 * rights. You may have additional license terms from the party that provided 00018 * you this software, covering your right to use that party's intellectual 00019 * property rights. 00020 * 00021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00022 * copy of the source code appearing in this file ("Covered Code") an 00023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00024 * base code distributed originally by Intel ("Original Intel Code") to copy, 00025 * make derivatives, distribute, use and display any portion of the Covered 00026 * Code in any form, with the right to sublicense such rights; and 00027 * 00028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00029 * license (with the right to sublicense), under only those claims of Intel 00030 * patents that are infringed by the Original Intel Code, to make, use, sell, 00031 * offer to sell, and import the Covered Code and derivative works thereof 00032 * solely to the minimum extent necessary to exercise the above copyright 00033 * license, and in no event shall the patent license extend to any additions 00034 * to or modifications of the Original Intel Code. No other license or right 00035 * is granted directly or by implication, estoppel or otherwise; 00036 * 00037 * The above copyright and patent license is granted only if the following 00038 * conditions are met: 00039 * 00040 * 3. Conditions 00041 * 00042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00043 * Redistribution of source code of any substantial portion of the Covered 00044 * Code or modification with rights to further distribute source must include 00045 * the above Copyright Notice, the above License, this list of Conditions, 00046 * and the following Disclaimer and Export Compliance provision. In addition, 00047 * Licensee must cause all Covered Code to which Licensee contributes to 00048 * contain a file documenting the changes Licensee made to create that Covered 00049 * Code and the date of any change. Licensee must include in that file the 00050 * documentation of any changes made by any predecessor Licensee. Licensee 00051 * must include a prominent statement that the modification is derived, 00052 * directly or indirectly, from Original Intel Code. 00053 * 00054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00055 * Redistribution of source code of any substantial portion of the Covered 00056 * Code or modification without rights to further distribute source must 00057 * include the following Disclaimer and Export Compliance provision in the 00058 * documentation and/or other materials provided with distribution. In 00059 * addition, Licensee may not authorize further sublicense of source of any 00060 * portion of the Covered Code, and must include terms to the effect that the 00061 * license from Licensee to its licensee is limited to the intellectual 00062 * property embodied in the software Licensee provides to its licensee, and 00063 * not to intellectual property embodied in modifications its licensee may 00064 * make. 00065 * 00066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00067 * substantial portion of the Covered Code or modification must reproduce the 00068 * above Copyright Notice, and the following Disclaimer and Export Compliance 00069 * provision in the documentation and/or other materials provided with the 00070 * distribution. 00071 * 00072 * 3.4. Intel retains all right, title, and interest in and to the Original 00073 * Intel Code. 00074 * 00075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00076 * Intel shall be used in advertising or otherwise to promote the sale, use or 00077 * other dealings in products derived from or relating to the Covered Code 00078 * without prior written authorization from Intel. 00079 * 00080 * 4. Disclaimer and Export Compliance 00081 * 00082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00088 * PARTICULAR PURPOSE. 00089 * 00090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00097 * LIMITED REMEDY. 00098 * 00099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00100 * software or system incorporating such software without first obtaining any 00101 * required license or other approval from the U. S. Department of Commerce or 00102 * any other agency or department of the United States Government. In the 00103 * event Licensee exports any such software from the United States or 00104 * re-exports any such software from a foreign destination, Licensee shall 00105 * ensure that the distribution and export/re-export of the software is in 00106 * compliance with all laws, regulations, orders, or other restrictions of the 00107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00108 * any of its subsidiaries will export/re-export any technical data, process, 00109 * software, or service, directly or indirectly, to any country for which the 00110 * United States government or any agency thereof requires an export license, 00111 * other governmental approval, or letter of assurance, without first obtaining 00112 * such license, approval or letter. 00113 * 00114 *****************************************************************************/ 00115 00116 00117 #define __UTMISC_C__ 00118 00119 #include "acpi.h" 00120 #include "accommon.h" 00121 #include "acnamesp.h" 00122 00123 00124 #define _COMPONENT ACPI_UTILITIES 00125 ACPI_MODULE_NAME ("utmisc") 00126 00127 00128 /******************************************************************************* 00129 * 00130 * FUNCTION: AcpiUtValidateException 00131 * 00132 * PARAMETERS: Status - The ACPI_STATUS code to be formatted 00133 * 00134 * RETURN: A string containing the exception text. NULL if exception is 00135 * not valid. 00136 * 00137 * DESCRIPTION: This function validates and translates an ACPI exception into 00138 * an ASCII string. 00139 * 00140 ******************************************************************************/ 00141 00142 const char * 00143 AcpiUtValidateException ( 00144 ACPI_STATUS Status) 00145 { 00146 UINT32 SubStatus; 00147 const char *Exception = NULL; 00148 00149 00150 ACPI_FUNCTION_ENTRY (); 00151 00152 00153 /* 00154 * Status is composed of two parts, a "type" and an actual code 00155 */ 00156 SubStatus = (Status & ~AE_CODE_MASK); 00157 00158 switch (Status & AE_CODE_MASK) 00159 { 00160 case AE_CODE_ENVIRONMENTAL: 00161 00162 if (SubStatus <= AE_CODE_ENV_MAX) 00163 { 00164 Exception = AcpiGbl_ExceptionNames_Env [SubStatus]; 00165 } 00166 break; 00167 00168 case AE_CODE_PROGRAMMER: 00169 00170 if (SubStatus <= AE_CODE_PGM_MAX) 00171 { 00172 Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus]; 00173 } 00174 break; 00175 00176 case AE_CODE_ACPI_TABLES: 00177 00178 if (SubStatus <= AE_CODE_TBL_MAX) 00179 { 00180 Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus]; 00181 } 00182 break; 00183 00184 case AE_CODE_AML: 00185 00186 if (SubStatus <= AE_CODE_AML_MAX) 00187 { 00188 Exception = AcpiGbl_ExceptionNames_Aml [SubStatus]; 00189 } 00190 break; 00191 00192 case AE_CODE_CONTROL: 00193 00194 if (SubStatus <= AE_CODE_CTRL_MAX) 00195 { 00196 Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus]; 00197 } 00198 break; 00199 00200 default: 00201 break; 00202 } 00203 00204 return (ACPI_CAST_PTR (const char, Exception)); 00205 } 00206 00207 00208 /******************************************************************************* 00209 * 00210 * FUNCTION: AcpiUtIsPciRootBridge 00211 * 00212 * PARAMETERS: Id - The HID/CID in string format 00213 * 00214 * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge 00215 * 00216 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. 00217 * 00218 ******************************************************************************/ 00219 00220 BOOLEAN 00221 AcpiUtIsPciRootBridge ( 00222 char *Id) 00223 { 00224 00225 /* 00226 * Check if this is a PCI root bridge. 00227 * ACPI 3.0+: check for a PCI Express root also. 00228 */ 00229 if (!(ACPI_STRCMP (Id, 00230 PCI_ROOT_HID_STRING)) || 00231 00232 !(ACPI_STRCMP (Id, 00233 PCI_EXPRESS_ROOT_HID_STRING))) 00234 { 00235 return (TRUE); 00236 } 00237 00238 return (FALSE); 00239 } 00240 00241 00242 /******************************************************************************* 00243 * 00244 * FUNCTION: AcpiUtIsAmlTable 00245 * 00246 * PARAMETERS: Table - An ACPI table 00247 * 00248 * RETURN: TRUE if table contains executable AML; FALSE otherwise 00249 * 00250 * DESCRIPTION: Check ACPI Signature for a table that contains AML code. 00251 * Currently, these are DSDT,SSDT,PSDT. All other table types are 00252 * data tables that do not contain AML code. 00253 * 00254 ******************************************************************************/ 00255 00256 BOOLEAN 00257 AcpiUtIsAmlTable ( 00258 ACPI_TABLE_HEADER *Table) 00259 { 00260 00261 /* These are the only tables that contain executable AML */ 00262 00263 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) || 00264 ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) || 00265 ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT)) 00266 { 00267 return (TRUE); 00268 } 00269 00270 return (FALSE); 00271 } 00272 00273 00274 /******************************************************************************* 00275 * 00276 * FUNCTION: AcpiUtAllocateOwnerId 00277 * 00278 * PARAMETERS: OwnerId - Where the new owner ID is returned 00279 * 00280 * RETURN: Status 00281 * 00282 * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to 00283 * track objects created by the table or method, to be deleted 00284 * when the method exits or the table is unloaded. 00285 * 00286 ******************************************************************************/ 00287 00288 ACPI_STATUS 00289 AcpiUtAllocateOwnerId ( 00290 ACPI_OWNER_ID *OwnerId) 00291 { 00292 UINT32 i; 00293 UINT32 j; 00294 UINT32 k; 00295 ACPI_STATUS Status; 00296 00297 00298 ACPI_FUNCTION_TRACE (UtAllocateOwnerId); 00299 00300 00301 /* Guard against multiple allocations of ID to the same location */ 00302 00303 if (*OwnerId) 00304 { 00305 ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId)); 00306 return_ACPI_STATUS (AE_ALREADY_EXISTS); 00307 } 00308 00309 /* Mutex for the global ID mask */ 00310 00311 Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 00312 if (ACPI_FAILURE (Status)) 00313 { 00314 return_ACPI_STATUS (Status); 00315 } 00316 00317 /* 00318 * Find a free owner ID, cycle through all possible IDs on repeated 00319 * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have 00320 * to be scanned twice. 00321 */ 00322 for (i = 0, j = AcpiGbl_LastOwnerIdIndex; 00323 i < (ACPI_NUM_OWNERID_MASKS + 1); 00324 i++, j++) 00325 { 00326 if (j >= ACPI_NUM_OWNERID_MASKS) 00327 { 00328 j = 0; /* Wraparound to start of mask array */ 00329 } 00330 00331 for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++) 00332 { 00333 if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX) 00334 { 00335 /* There are no free IDs in this mask */ 00336 00337 break; 00338 } 00339 00340 if (!(AcpiGbl_OwnerIdMask[j] & (1 << k))) 00341 { 00342 /* 00343 * Found a free ID. The actual ID is the bit index plus one, 00344 * making zero an invalid Owner ID. Save this as the last ID 00345 * allocated and update the global ID mask. 00346 */ 00347 AcpiGbl_OwnerIdMask[j] |= (1 << k); 00348 00349 AcpiGbl_LastOwnerIdIndex = (UINT8) j; 00350 AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1); 00351 00352 /* 00353 * Construct encoded ID from the index and bit position 00354 * 00355 * Note: Last [j].k (bit 255) is never used and is marked 00356 * permanently allocated (prevents +1 overflow) 00357 */ 00358 *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j)); 00359 00360 ACPI_DEBUG_PRINT ((ACPI_DB_VALUES, 00361 "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId)); 00362 goto Exit; 00363 } 00364 } 00365 00366 AcpiGbl_NextOwnerIdOffset = 0; 00367 } 00368 00369 /* 00370 * All OwnerIds have been allocated. This typically should 00371 * not happen since the IDs are reused after deallocation. The IDs are 00372 * allocated upon table load (one per table) and method execution, and 00373 * they are released when a table is unloaded or a method completes 00374 * execution. 00375 * 00376 * If this error happens, there may be very deep nesting of invoked control 00377 * methods, or there may be a bug where the IDs are not released. 00378 */ 00379 Status = AE_OWNER_ID_LIMIT; 00380 ACPI_ERROR ((AE_INFO, 00381 "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT")); 00382 00383 Exit: 00384 (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 00385 return_ACPI_STATUS (Status); 00386 } 00387 00388 00389 /******************************************************************************* 00390 * 00391 * FUNCTION: AcpiUtReleaseOwnerId 00392 * 00393 * PARAMETERS: OwnerIdPtr - Pointer to a previously allocated OwnerID 00394 * 00395 * RETURN: None. No error is returned because we are either exiting a 00396 * control method or unloading a table. Either way, we would 00397 * ignore any error anyway. 00398 * 00399 * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255 00400 * 00401 ******************************************************************************/ 00402 00403 void 00404 AcpiUtReleaseOwnerId ( 00405 ACPI_OWNER_ID *OwnerIdPtr) 00406 { 00407 ACPI_OWNER_ID OwnerId = *OwnerIdPtr; 00408 ACPI_STATUS Status; 00409 UINT32 Index; 00410 UINT32 Bit; 00411 00412 00413 ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId); 00414 00415 00416 /* Always clear the input OwnerId (zero is an invalid ID) */ 00417 00418 *OwnerIdPtr = 0; 00419 00420 /* Zero is not a valid OwnerID */ 00421 00422 if (OwnerId == 0) 00423 { 00424 ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId)); 00425 return_VOID; 00426 } 00427 00428 /* Mutex for the global ID mask */ 00429 00430 Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 00431 if (ACPI_FAILURE (Status)) 00432 { 00433 return_VOID; 00434 } 00435 00436 /* Normalize the ID to zero */ 00437 00438 OwnerId--; 00439 00440 /* Decode ID to index/offset pair */ 00441 00442 Index = ACPI_DIV_32 (OwnerId); 00443 Bit = 1 << ACPI_MOD_32 (OwnerId); 00444 00445 /* Free the owner ID only if it is valid */ 00446 00447 if (AcpiGbl_OwnerIdMask[Index] & Bit) 00448 { 00449 AcpiGbl_OwnerIdMask[Index] ^= Bit; 00450 } 00451 else 00452 { 00453 ACPI_ERROR ((AE_INFO, 00454 "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1)); 00455 } 00456 00457 (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 00458 return_VOID; 00459 } 00460 00461 00462 /******************************************************************************* 00463 * 00464 * FUNCTION: AcpiUtStrupr (strupr) 00465 * 00466 * PARAMETERS: SrcString - The source string to convert 00467 * 00468 * RETURN: None 00469 * 00470 * DESCRIPTION: Convert string to uppercase 00471 * 00472 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 00473 * 00474 ******************************************************************************/ 00475 00476 void 00477 AcpiUtStrupr ( 00478 char *SrcString) 00479 { 00480 char *String; 00481 00482 00483 ACPI_FUNCTION_ENTRY (); 00484 00485 00486 if (!SrcString) 00487 { 00488 return; 00489 } 00490 00491 /* Walk entire string, uppercasing the letters */ 00492 00493 for (String = SrcString; *String; String++) 00494 { 00495 *String = (char) ACPI_TOUPPER (*String); 00496 } 00497 00498 return; 00499 } 00500 00501 00502 #ifdef ACPI_ASL_COMPILER 00503 /******************************************************************************* 00504 * 00505 * FUNCTION: AcpiUtStrlwr (strlwr) 00506 * 00507 * PARAMETERS: SrcString - The source string to convert 00508 * 00509 * RETURN: None 00510 * 00511 * DESCRIPTION: Convert string to lowercase 00512 * 00513 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 00514 * 00515 ******************************************************************************/ 00516 00517 void 00518 AcpiUtStrlwr ( 00519 char *SrcString) 00520 { 00521 char *String; 00522 00523 00524 ACPI_FUNCTION_ENTRY (); 00525 00526 00527 if (!SrcString) 00528 { 00529 return; 00530 } 00531 00532 /* Walk entire string, lowercasing the letters */ 00533 00534 for (String = SrcString; *String; String++) 00535 { 00536 *String = (char) ACPI_TOLOWER (*String); 00537 } 00538 00539 return; 00540 } 00541 #endif 00542 00543 00544 /******************************************************************************* 00545 * 00546 * FUNCTION: AcpiUtPrintString 00547 * 00548 * PARAMETERS: String - Null terminated ASCII string 00549 * MaxLength - Maximum output length 00550 * 00551 * RETURN: None 00552 * 00553 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 00554 * sequences. 00555 * 00556 ******************************************************************************/ 00557 00558 void 00559 AcpiUtPrintString ( 00560 char *String, 00561 UINT8 MaxLength) 00562 { 00563 UINT32 i; 00564 00565 00566 if (!String) 00567 { 00568 AcpiOsPrintf ("<\"NULL STRING PTR\">"); 00569 return; 00570 } 00571 00572 AcpiOsPrintf ("\""); 00573 for (i = 0; String[i] && (i < MaxLength); i++) 00574 { 00575 /* Escape sequences */ 00576 00577 switch (String[i]) 00578 { 00579 case 0x07: 00580 AcpiOsPrintf ("\\a"); /* BELL */ 00581 break; 00582 00583 case 0x08: 00584 AcpiOsPrintf ("\\b"); /* BACKSPACE */ 00585 break; 00586 00587 case 0x0C: 00588 AcpiOsPrintf ("\\f"); /* FORMFEED */ 00589 break; 00590 00591 case 0x0A: 00592 AcpiOsPrintf ("\\n"); /* LINEFEED */ 00593 break; 00594 00595 case 0x0D: 00596 AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/ 00597 break; 00598 00599 case 0x09: 00600 AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */ 00601 break; 00602 00603 case 0x0B: 00604 AcpiOsPrintf ("\\v"); /* VERTICAL TAB */ 00605 break; 00606 00607 case '\'': /* Single Quote */ 00608 case '\"': /* Double Quote */ 00609 case '\\': /* Backslash */ 00610 AcpiOsPrintf ("\\%c", (int) String[i]); 00611 break; 00612 00613 default: 00614 00615 /* Check for printable character or hex escape */ 00616 00617 if (ACPI_IS_PRINT (String[i])) 00618 { 00619 /* This is a normal character */ 00620 00621 AcpiOsPrintf ("%c", (int) String[i]); 00622 } 00623 else 00624 { 00625 /* All others will be Hex escapes */ 00626 00627 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]); 00628 } 00629 break; 00630 } 00631 } 00632 AcpiOsPrintf ("\""); 00633 00634 if (i == MaxLength && String[i]) 00635 { 00636 AcpiOsPrintf ("..."); 00637 } 00638 } 00639 00640 00641 /******************************************************************************* 00642 * 00643 * FUNCTION: AcpiUtDwordByteSwap 00644 * 00645 * PARAMETERS: Value - Value to be converted 00646 * 00647 * RETURN: UINT32 integer with bytes swapped 00648 * 00649 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 00650 * 00651 ******************************************************************************/ 00652 00653 UINT32 00654 AcpiUtDwordByteSwap ( 00655 UINT32 Value) 00656 { 00657 union 00658 { 00659 UINT32 Value; 00660 UINT8 Bytes[4]; 00661 } Out; 00662 union 00663 { 00664 UINT32 Value; 00665 UINT8 Bytes[4]; 00666 } In; 00667 00668 00669 ACPI_FUNCTION_ENTRY (); 00670 00671 00672 In.Value = Value; 00673 00674 Out.Bytes[0] = In.Bytes[3]; 00675 Out.Bytes[1] = In.Bytes[2]; 00676 Out.Bytes[2] = In.Bytes[1]; 00677 Out.Bytes[3] = In.Bytes[0]; 00678 00679 return (Out.Value); 00680 } 00681 00682 00683 /******************************************************************************* 00684 * 00685 * FUNCTION: AcpiUtSetIntegerWidth 00686 * 00687 * PARAMETERS: Revision From DSDT header 00688 * 00689 * RETURN: None 00690 * 00691 * DESCRIPTION: Set the global integer bit width based upon the revision 00692 * of the DSDT. For Revision 1 and 0, Integers are 32 bits. 00693 * For Revision 2 and above, Integers are 64 bits. Yes, this 00694 * makes a difference. 00695 * 00696 ******************************************************************************/ 00697 00698 void 00699 AcpiUtSetIntegerWidth ( 00700 UINT8 Revision) 00701 { 00702 00703 if (Revision < 2) 00704 { 00705 /* 32-bit case */ 00706 00707 AcpiGbl_IntegerBitWidth = 32; 00708 AcpiGbl_IntegerNybbleWidth = 8; 00709 AcpiGbl_IntegerByteWidth = 4; 00710 } 00711 else 00712 { 00713 /* 64-bit case (ACPI 2.0+) */ 00714 00715 AcpiGbl_IntegerBitWidth = 64; 00716 AcpiGbl_IntegerNybbleWidth = 16; 00717 AcpiGbl_IntegerByteWidth = 8; 00718 } 00719 } 00720 00721 00722 #ifdef ACPI_DEBUG_OUTPUT 00723 /******************************************************************************* 00724 * 00725 * FUNCTION: AcpiUtDisplayInitPathname 00726 * 00727 * PARAMETERS: Type - Object type of the node 00728 * ObjHandle - Handle whose pathname will be displayed 00729 * Path - Additional path string to be appended. 00730 * (NULL if no extra path) 00731 * 00732 * RETURN: ACPI_STATUS 00733 * 00734 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY 00735 * 00736 ******************************************************************************/ 00737 00738 void 00739 AcpiUtDisplayInitPathname ( 00740 UINT8 Type, 00741 ACPI_NAMESPACE_NODE *ObjHandle, 00742 char *Path) 00743 { 00744 ACPI_STATUS Status; 00745 ACPI_BUFFER Buffer; 00746 00747 00748 ACPI_FUNCTION_ENTRY (); 00749 00750 00751 /* Only print the path if the appropriate debug level is enabled */ 00752 00753 if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES)) 00754 { 00755 return; 00756 } 00757 00758 /* Get the full pathname to the node */ 00759 00760 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 00761 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 00762 if (ACPI_FAILURE (Status)) 00763 { 00764 return; 00765 } 00766 00767 /* Print what we're doing */ 00768 00769 switch (Type) 00770 { 00771 case ACPI_TYPE_METHOD: 00772 AcpiOsPrintf ("Executing "); 00773 break; 00774 00775 default: 00776 AcpiOsPrintf ("Initializing "); 00777 break; 00778 } 00779 00780 /* Print the object type and pathname */ 00781 00782 AcpiOsPrintf ("%-12s %s", 00783 AcpiUtGetTypeName (Type), (char *) Buffer.Pointer); 00784 00785 /* Extra path is used to append names like _STA, _INI, etc. */ 00786 00787 if (Path) 00788 { 00789 AcpiOsPrintf (".%s", Path); 00790 } 00791 AcpiOsPrintf ("\n"); 00792 00793 ACPI_FREE (Buffer.Pointer); 00794 } 00795 #endif 00796 00797 00798 /******************************************************************************* 00799 * 00800 * FUNCTION: AcpiUtValidAcpiChar 00801 * 00802 * PARAMETERS: Char - The character to be examined 00803 * Position - Byte position (0-3) 00804 * 00805 * RETURN: TRUE if the character is valid, FALSE otherwise 00806 * 00807 * DESCRIPTION: Check for a valid ACPI character. Must be one of: 00808 * 1) Upper case alpha 00809 * 2) numeric 00810 * 3) underscore 00811 * 00812 * We allow a '!' as the last character because of the ASF! table 00813 * 00814 ******************************************************************************/ 00815 00816 BOOLEAN 00817 AcpiUtValidAcpiChar ( 00818 char Character, 00819 UINT32 Position) 00820 { 00821 00822 if (!((Character >= 'A' && Character <= 'Z') || 00823 (Character >= '0' && Character <= '9') || 00824 (Character == '_'))) 00825 { 00826 /* Allow a '!' in the last position */ 00827 00828 if (Character == '!' && Position == 3) 00829 { 00830 return (TRUE); 00831 } 00832 00833 return (FALSE); 00834 } 00835 00836 return (TRUE); 00837 } 00838 00839 00840 /******************************************************************************* 00841 * 00842 * FUNCTION: AcpiUtValidAcpiName 00843 * 00844 * PARAMETERS: Name - The name to be examined 00845 * 00846 * RETURN: TRUE if the name is valid, FALSE otherwise 00847 * 00848 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 00849 * 1) Upper case alpha 00850 * 2) numeric 00851 * 3) underscore 00852 * 00853 ******************************************************************************/ 00854 00855 BOOLEAN 00856 AcpiUtValidAcpiName ( 00857 UINT32 Name) 00858 { 00859 UINT32 i; 00860 00861 00862 ACPI_FUNCTION_ENTRY (); 00863 00864 00865 for (i = 0; i < ACPI_NAME_SIZE; i++) 00866 { 00867 if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i)) 00868 { 00869 return (FALSE); 00870 } 00871 } 00872 00873 return (TRUE); 00874 } 00875 00876 00877 /******************************************************************************* 00878 * 00879 * FUNCTION: AcpiUtRepairName 00880 * 00881 * PARAMETERS: Name - The ACPI name to be repaired 00882 * 00883 * RETURN: Repaired version of the name 00884 * 00885 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 00886 * return the new name. NOTE: the Name parameter must reside in 00887 * read/write memory, cannot be a const. 00888 * 00889 * An ACPI Name must consist of valid ACPI characters. We will repair the name 00890 * if necessary because we don't want to abort because of this, but we want 00891 * all namespace names to be printable. A warning message is appropriate. 00892 * 00893 * This issue came up because there are in fact machines that exhibit 00894 * this problem, and we want to be able to enable ACPI support for them, 00895 * even though there are a few bad names. 00896 * 00897 ******************************************************************************/ 00898 00899 void 00900 AcpiUtRepairName ( 00901 char *Name) 00902 { 00903 UINT32 i; 00904 BOOLEAN FoundBadChar = FALSE; 00905 00906 00907 ACPI_FUNCTION_NAME (UtRepairName); 00908 00909 00910 /* Check each character in the name */ 00911 00912 for (i = 0; i < ACPI_NAME_SIZE; i++) 00913 { 00914 if (AcpiUtValidAcpiChar (Name[i], i)) 00915 { 00916 continue; 00917 } 00918 00919 /* 00920 * Replace a bad character with something printable, yet technically 00921 * still invalid. This prevents any collisions with existing "good" 00922 * names in the namespace. 00923 */ 00924 Name[i] = '*'; 00925 FoundBadChar = TRUE; 00926 } 00927 00928 if (FoundBadChar) 00929 { 00930 /* Report warning only if in strict mode or debug mode */ 00931 00932 if (!AcpiGbl_EnableInterpreterSlack) 00933 { 00934 ACPI_WARNING ((AE_INFO, 00935 "Found bad character(s) in name, repaired: [%4.4s]\n", Name)); 00936 } 00937 else 00938 { 00939 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 00940 "Found bad character(s) in name, repaired: [%4.4s]\n", Name)); 00941 } 00942 } 00943 } 00944 00945 00946 /******************************************************************************* 00947 * 00948 * FUNCTION: AcpiUtStrtoul64 00949 * 00950 * PARAMETERS: String - Null terminated string 00951 * Base - Radix of the string: 16 or ACPI_ANY_BASE; 00952 * ACPI_ANY_BASE means 'in behalf of ToInteger' 00953 * RetInteger - Where the converted integer is returned 00954 * 00955 * RETURN: Status and Converted value 00956 * 00957 * DESCRIPTION: Convert a string into an unsigned value. Performs either a 00958 * 32-bit or 64-bit conversion, depending on the current mode 00959 * of the interpreter. 00960 * NOTE: Does not support Octal strings, not needed. 00961 * 00962 ******************************************************************************/ 00963 00964 ACPI_STATUS 00965 AcpiUtStrtoul64 ( 00966 char *String, 00967 UINT32 Base, 00968 UINT64 *RetInteger) 00969 { 00970 UINT32 ThisDigit = 0; 00971 UINT64 ReturnValue = 0; 00972 UINT64 Quotient; 00973 UINT64 Dividend; 00974 UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE); 00975 UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4); 00976 UINT8 ValidDigits = 0; 00977 UINT8 SignOf0x = 0; 00978 UINT8 Term = 0; 00979 00980 00981 ACPI_FUNCTION_TRACE_STR (UtStroul64, String); 00982 00983 00984 switch (Base) 00985 { 00986 case ACPI_ANY_BASE: 00987 case 16: 00988 break; 00989 00990 default: 00991 /* Invalid Base */ 00992 return_ACPI_STATUS (AE_BAD_PARAMETER); 00993 } 00994 00995 if (!String) 00996 { 00997 goto ErrorExit; 00998 } 00999 01000 /* Skip over any white space in the buffer */ 01001 01002 while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t')) 01003 { 01004 String++; 01005 } 01006 01007 if (ToIntegerOp) 01008 { 01009 /* 01010 * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 01011 * We need to determine if it is decimal or hexadecimal. 01012 */ 01013 if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x')) 01014 { 01015 SignOf0x = 1; 01016 Base = 16; 01017 01018 /* Skip over the leading '0x' */ 01019 String += 2; 01020 } 01021 else 01022 { 01023 Base = 10; 01024 } 01025 } 01026 01027 /* Any string left? Check that '0x' is not followed by white space. */ 01028 01029 if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t') 01030 { 01031 if (ToIntegerOp) 01032 { 01033 goto ErrorExit; 01034 } 01035 else 01036 { 01037 goto AllDone; 01038 } 01039 } 01040 01041 /* 01042 * Perform a 32-bit or 64-bit conversion, depending upon the current 01043 * execution mode of the interpreter 01044 */ 01045 Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 01046 01047 /* Main loop: convert the string to a 32- or 64-bit integer */ 01048 01049 while (*String) 01050 { 01051 if (ACPI_IS_DIGIT (*String)) 01052 { 01053 /* Convert ASCII 0-9 to Decimal value */ 01054 01055 ThisDigit = ((UINT8) *String) - '0'; 01056 } 01057 else if (Base == 10) 01058 { 01059 /* Digit is out of range; possible in ToInteger case only */ 01060 01061 Term = 1; 01062 } 01063 else 01064 { 01065 ThisDigit = (UINT8) ACPI_TOUPPER (*String); 01066 if (ACPI_IS_XDIGIT ((char) ThisDigit)) 01067 { 01068 /* Convert ASCII Hex char to value */ 01069 01070 ThisDigit = ThisDigit - 'A' + 10; 01071 } 01072 else 01073 { 01074 Term = 1; 01075 } 01076 } 01077 01078 if (Term) 01079 { 01080 if (ToIntegerOp) 01081 { 01082 goto ErrorExit; 01083 } 01084 else 01085 { 01086 break; 01087 } 01088 } 01089 else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 01090 { 01091 /* Skip zeros */ 01092 String++; 01093 continue; 01094 } 01095 01096 ValidDigits++; 01097 01098 if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32))) 01099 { 01100 /* 01101 * This is ToInteger operation case. 01102 * No any restrictions for string-to-integer conversion, 01103 * see ACPI spec. 01104 */ 01105 goto ErrorExit; 01106 } 01107 01108 /* Divide the digit into the correct position */ 01109 01110 (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit), 01111 Base, &Quotient, NULL); 01112 01113 if (ReturnValue > Quotient) 01114 { 01115 if (ToIntegerOp) 01116 { 01117 goto ErrorExit; 01118 } 01119 else 01120 { 01121 break; 01122 } 01123 } 01124 01125 ReturnValue *= Base; 01126 ReturnValue += ThisDigit; 01127 String++; 01128 } 01129 01130 /* All done, normal exit */ 01131 01132 AllDone: 01133 01134 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 01135 ACPI_FORMAT_UINT64 (ReturnValue))); 01136 01137 *RetInteger = ReturnValue; 01138 return_ACPI_STATUS (AE_OK); 01139 01140 01141 ErrorExit: 01142 /* Base was set/validated above */ 01143 01144 if (Base == 10) 01145 { 01146 return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 01147 } 01148 else 01149 { 01150 return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 01151 } 01152 } 01153 01154 01155 /******************************************************************************* 01156 * 01157 * FUNCTION: AcpiUtCreateUpdateStateAndPush 01158 * 01159 * PARAMETERS: Object - Object to be added to the new state 01160 * Action - Increment/Decrement 01161 * StateList - List the state will be added to 01162 * 01163 * RETURN: Status 01164 * 01165 * DESCRIPTION: Create a new state and push it 01166 * 01167 ******************************************************************************/ 01168 01169 ACPI_STATUS 01170 AcpiUtCreateUpdateStateAndPush ( 01171 ACPI_OPERAND_OBJECT *Object, 01172 UINT16 Action, 01173 ACPI_GENERIC_STATE **StateList) 01174 { 01175 ACPI_GENERIC_STATE *State; 01176 01177 01178 ACPI_FUNCTION_ENTRY (); 01179 01180 01181 /* Ignore null objects; these are expected */ 01182 01183 if (!Object) 01184 { 01185 return (AE_OK); 01186 } 01187 01188 State = AcpiUtCreateUpdateState (Object, Action); 01189 if (!State) 01190 { 01191 return (AE_NO_MEMORY); 01192 } 01193 01194 AcpiUtPushGenericState (StateList, State); 01195 return (AE_OK); 01196 } 01197 01198 01199 /******************************************************************************* 01200 * 01201 * FUNCTION: AcpiUtWalkPackageTree 01202 * 01203 * PARAMETERS: SourceObject - The package to walk 01204 * TargetObject - Target object (if package is being copied) 01205 * WalkCallback - Called once for each package element 01206 * Context - Passed to the callback function 01207 * 01208 * RETURN: Status 01209 * 01210 * DESCRIPTION: Walk through a package 01211 * 01212 ******************************************************************************/ 01213 01214 ACPI_STATUS 01215 AcpiUtWalkPackageTree ( 01216 ACPI_OPERAND_OBJECT *SourceObject, 01217 void *TargetObject, 01218 ACPI_PKG_CALLBACK WalkCallback, 01219 void *Context) 01220 { 01221 ACPI_STATUS Status = AE_OK; 01222 ACPI_GENERIC_STATE *StateList = NULL; 01223 ACPI_GENERIC_STATE *State; 01224 UINT32 ThisIndex; 01225 ACPI_OPERAND_OBJECT *ThisSourceObj; 01226 01227 01228 ACPI_FUNCTION_TRACE (UtWalkPackageTree); 01229 01230 01231 State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 01232 if (!State) 01233 { 01234 return_ACPI_STATUS (AE_NO_MEMORY); 01235 } 01236 01237 while (State) 01238 { 01239 /* Get one element of the package */ 01240 01241 ThisIndex = State->Pkg.Index; 01242 ThisSourceObj = (ACPI_OPERAND_OBJECT *) 01243 State->Pkg.SourceObject->Package.Elements[ThisIndex]; 01244 01245 /* 01246 * Check for: 01247 * 1) An uninitialized package element. It is completely 01248 * legal to declare a package and leave it uninitialized 01249 * 2) Not an internal object - can be a namespace node instead 01250 * 3) Any type other than a package. Packages are handled in else 01251 * case below. 01252 */ 01253 if ((!ThisSourceObj) || 01254 (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) || 01255 (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE)) 01256 { 01257 Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 01258 State, Context); 01259 if (ACPI_FAILURE (Status)) 01260 { 01261 return_ACPI_STATUS (Status); 01262 } 01263 01264 State->Pkg.Index++; 01265 while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count) 01266 { 01267 /* 01268 * We've handled all of the objects at this level, This means 01269 * that we have just completed a package. That package may 01270 * have contained one or more packages itself. 01271 * 01272 * Delete this state and pop the previous state (package). 01273 */ 01274 AcpiUtDeleteGenericState (State); 01275 State = AcpiUtPopGenericState (&StateList); 01276 01277 /* Finished when there are no more states */ 01278 01279 if (!State) 01280 { 01281 /* 01282 * We have handled all of the objects in the top level 01283 * package just add the length of the package objects 01284 * and exit 01285 */ 01286 return_ACPI_STATUS (AE_OK); 01287 } 01288 01289 /* 01290 * Go back up a level and move the index past the just 01291 * completed package object. 01292 */ 01293 State->Pkg.Index++; 01294 } 01295 } 01296 else 01297 { 01298 /* This is a subobject of type package */ 01299 01300 Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, 01301 State, Context); 01302 if (ACPI_FAILURE (Status)) 01303 { 01304 return_ACPI_STATUS (Status); 01305 } 01306 01307 /* 01308 * Push the current state and create a new one 01309 * The callback above returned a new target package object. 01310 */ 01311 AcpiUtPushGenericState (&StateList, State); 01312 State = AcpiUtCreatePkgState (ThisSourceObj, 01313 State->Pkg.ThisTargetObj, 0); 01314 if (!State) 01315 { 01316 /* Free any stacked Update State objects */ 01317 01318 while (StateList) 01319 { 01320 State = AcpiUtPopGenericState (&StateList); 01321 AcpiUtDeleteGenericState (State); 01322 } 01323 return_ACPI_STATUS (AE_NO_MEMORY); 01324 } 01325 } 01326 } 01327 01328 /* We should never get here */ 01329 01330 return_ACPI_STATUS (AE_AML_INTERNAL); 01331 } 01332 01333 Generated on Sat May 26 2012 04:25:57 for ReactOS by
1.7.6.1
|