ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

utmisc.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.