455 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			455 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*******************************************************************************
 | |
|  *
 | |
|  * Module Name: utmisc - common utility procedures
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| 
 | |
| /*
 | |
|  * Copyright (C) 2000 - 2014, Intel Corp.
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions
 | |
|  * are met:
 | |
|  * 1. Redistributions of source code must retain the above copyright
 | |
|  *    notice, this list of conditions, and the following disclaimer,
 | |
|  *    without modification.
 | |
|  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 | |
|  *    substantially similar to the "NO WARRANTY" disclaimer below
 | |
|  *    ("Disclaimer") and any redistribution must be conditioned upon
 | |
|  *    including a substantially similar Disclaimer requirement for further
 | |
|  *    binary redistribution.
 | |
|  * 3. Neither the names of the above-listed copyright holders nor the names
 | |
|  *    of any contributors may be used to endorse or promote products derived
 | |
|  *    from this software without specific prior written permission.
 | |
|  *
 | |
|  * Alternatively, this software may be distributed under the terms of the
 | |
|  * GNU General Public License ("GPL") version 2 as published by the Free
 | |
|  * Software Foundation.
 | |
|  *
 | |
|  * NO WARRANTY
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
|  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 | |
|  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
|  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | |
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | |
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | |
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | |
|  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 | |
|  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | |
|  * POSSIBILITY OF SUCH DAMAGES.
 | |
|  */
 | |
| 
 | |
| #include "acpi.h"
 | |
| #include "accommon.h"
 | |
| #include "acnamesp.h"
 | |
| 
 | |
| 
 | |
| #define _COMPONENT          ACPI_UTILITIES
 | |
|         ACPI_MODULE_NAME    ("utmisc")
 | |
| 
 | |
| 
 | |
| /*******************************************************************************
 | |
|  *
 | |
|  * FUNCTION:    AcpiUtIsPciRootBridge
 | |
|  *
 | |
|  * PARAMETERS:  Id              - The HID/CID in string format
 | |
|  *
 | |
|  * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
 | |
|  *
 | |
|  * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| 
 | |
| BOOLEAN
 | |
| AcpiUtIsPciRootBridge (
 | |
|     char                    *Id)
 | |
| {
 | |
| 
 | |
|     /*
 | |
|      * Check if this is a PCI root bridge.
 | |
|      * ACPI 3.0+: check for a PCI Express root also.
 | |
|      */
 | |
|     if (!(ACPI_STRCMP (Id,
 | |
|             PCI_ROOT_HID_STRING)) ||
 | |
| 
 | |
|         !(ACPI_STRCMP (Id,
 | |
|             PCI_EXPRESS_ROOT_HID_STRING)))
 | |
|     {
 | |
|         return (TRUE);
 | |
|     }
 | |
| 
 | |
|     return (FALSE);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*******************************************************************************
 | |
|  *
 | |
|  * FUNCTION:    AcpiUtIsAmlTable
 | |
|  *
 | |
|  * PARAMETERS:  Table               - An ACPI table
 | |
|  *
 | |
|  * RETURN:      TRUE if table contains executable AML; FALSE otherwise
 | |
|  *
 | |
|  * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
 | |
|  *              Currently, these are DSDT,SSDT,PSDT. All other table types are
 | |
|  *              data tables that do not contain AML code.
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| 
 | |
| BOOLEAN
 | |
| AcpiUtIsAmlTable (
 | |
|     ACPI_TABLE_HEADER       *Table)
 | |
| {
 | |
| 
 | |
|     /* These are the only tables that contain executable AML */
 | |
| 
 | |
|     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
 | |
|         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
 | |
|         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
 | |
|     {
 | |
|         return (TRUE);
 | |
|     }
 | |
| 
 | |
|     return (FALSE);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*******************************************************************************
 | |
|  *
 | |
|  * FUNCTION:    AcpiUtDwordByteSwap
 | |
|  *
 | |
|  * PARAMETERS:  Value           - Value to be converted
 | |
|  *
 | |
|  * RETURN:      UINT32 integer with bytes swapped
 | |
|  *
 | |
|  * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| 
 | |
| UINT32
 | |
| AcpiUtDwordByteSwap (
 | |
|     UINT32                  Value)
 | |
| {
 | |
|     union
 | |
|     {
 | |
|         UINT32              Value;
 | |
|         UINT8               Bytes[4];
 | |
|     } Out;
 | |
|     union
 | |
|     {
 | |
|         UINT32              Value;
 | |
|         UINT8               Bytes[4];
 | |
|     } In;
 | |
| 
 | |
| 
 | |
|     ACPI_FUNCTION_ENTRY ();
 | |
| 
 | |
| 
 | |
|     In.Value = Value;
 | |
| 
 | |
|     Out.Bytes[0] = In.Bytes[3];
 | |
|     Out.Bytes[1] = In.Bytes[2];
 | |
|     Out.Bytes[2] = In.Bytes[1];
 | |
|     Out.Bytes[3] = In.Bytes[0];
 | |
| 
 | |
|     return (Out.Value);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*******************************************************************************
 | |
|  *
 | |
|  * FUNCTION:    AcpiUtSetIntegerWidth
 | |
|  *
 | |
|  * PARAMETERS:  Revision            From DSDT header
 | |
|  *
 | |
|  * RETURN:      None
 | |
|  *
 | |
|  * DESCRIPTION: Set the global integer bit width based upon the revision
 | |
|  *              of the DSDT. For Revision 1 and 0, Integers are 32 bits.
 | |
|  *              For Revision 2 and above, Integers are 64 bits. Yes, this
 | |
|  *              makes a difference.
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| 
 | |
| void
 | |
| AcpiUtSetIntegerWidth (
 | |
|     UINT8                   Revision)
 | |
| {
 | |
| 
 | |
|     if (Revision < 2)
 | |
|     {
 | |
|         /* 32-bit case */
 | |
| 
 | |
|         AcpiGbl_IntegerBitWidth    = 32;
 | |
|         AcpiGbl_IntegerNybbleWidth = 8;
 | |
|         AcpiGbl_IntegerByteWidth   = 4;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         /* 64-bit case (ACPI 2.0+) */
 | |
| 
 | |
|         AcpiGbl_IntegerBitWidth    = 64;
 | |
|         AcpiGbl_IntegerNybbleWidth = 16;
 | |
|         AcpiGbl_IntegerByteWidth   = 8;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*******************************************************************************
 | |
|  *
 | |
|  * FUNCTION:    AcpiUtCreateUpdateStateAndPush
 | |
|  *
 | |
|  * PARAMETERS:  Object          - Object to be added to the new state
 | |
|  *              Action          - Increment/Decrement
 | |
|  *              StateList       - List the state will be added to
 | |
|  *
 | |
|  * RETURN:      Status
 | |
|  *
 | |
|  * DESCRIPTION: Create a new state and push it
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| 
 | |
| ACPI_STATUS
 | |
| AcpiUtCreateUpdateStateAndPush (
 | |
|     ACPI_OPERAND_OBJECT     *Object,
 | |
|     UINT16                  Action,
 | |
|     ACPI_GENERIC_STATE      **StateList)
 | |
| {
 | |
|     ACPI_GENERIC_STATE       *State;
 | |
| 
 | |
| 
 | |
|     ACPI_FUNCTION_ENTRY ();
 | |
| 
 | |
| 
 | |
|     /* Ignore null objects; these are expected */
 | |
| 
 | |
|     if (!Object)
 | |
|     {
 | |
|         return (AE_OK);
 | |
|     }
 | |
| 
 | |
|     State = AcpiUtCreateUpdateState (Object, Action);
 | |
|     if (!State)
 | |
|     {
 | |
|         return (AE_NO_MEMORY);
 | |
|     }
 | |
| 
 | |
|     AcpiUtPushGenericState (StateList, State);
 | |
|     return (AE_OK);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*******************************************************************************
 | |
|  *
 | |
|  * FUNCTION:    AcpiUtWalkPackageTree
 | |
|  *
 | |
|  * PARAMETERS:  SourceObject        - The package to walk
 | |
|  *              TargetObject        - Target object (if package is being copied)
 | |
|  *              WalkCallback        - Called once for each package element
 | |
|  *              Context             - Passed to the callback function
 | |
|  *
 | |
|  * RETURN:      Status
 | |
|  *
 | |
|  * DESCRIPTION: Walk through a package
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| 
 | |
| ACPI_STATUS
 | |
| AcpiUtWalkPackageTree (
 | |
|     ACPI_OPERAND_OBJECT     *SourceObject,
 | |
|     void                    *TargetObject,
 | |
|     ACPI_PKG_CALLBACK       WalkCallback,
 | |
|     void                    *Context)
 | |
| {
 | |
|     ACPI_STATUS             Status = AE_OK;
 | |
|     ACPI_GENERIC_STATE      *StateList = NULL;
 | |
|     ACPI_GENERIC_STATE      *State;
 | |
|     UINT32                  ThisIndex;
 | |
|     ACPI_OPERAND_OBJECT     *ThisSourceObj;
 | |
| 
 | |
| 
 | |
|     ACPI_FUNCTION_TRACE (UtWalkPackageTree);
 | |
| 
 | |
| 
 | |
|     State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
 | |
|     if (!State)
 | |
|     {
 | |
|         return_ACPI_STATUS (AE_NO_MEMORY);
 | |
|     }
 | |
| 
 | |
|     while (State)
 | |
|     {
 | |
|         /* Get one element of the package */
 | |
| 
 | |
|         ThisIndex     = State->Pkg.Index;
 | |
|         ThisSourceObj = (ACPI_OPERAND_OBJECT *)
 | |
|                         State->Pkg.SourceObject->Package.Elements[ThisIndex];
 | |
| 
 | |
|         /*
 | |
|          * Check for:
 | |
|          * 1) An uninitialized package element. It is completely
 | |
|          *    legal to declare a package and leave it uninitialized
 | |
|          * 2) Not an internal object - can be a namespace node instead
 | |
|          * 3) Any type other than a package. Packages are handled in else
 | |
|          *    case below.
 | |
|          */
 | |
|         if ((!ThisSourceObj) ||
 | |
|             (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
 | |
|             (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
 | |
|         {
 | |
|             Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
 | |
|                                     State, Context);
 | |
|             if (ACPI_FAILURE (Status))
 | |
|             {
 | |
|                 return_ACPI_STATUS (Status);
 | |
|             }
 | |
| 
 | |
|             State->Pkg.Index++;
 | |
|             while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
 | |
|             {
 | |
|                 /*
 | |
|                  * We've handled all of the objects at this level,  This means
 | |
|                  * that we have just completed a package. That package may
 | |
|                  * have contained one or more packages itself.
 | |
|                  *
 | |
|                  * Delete this state and pop the previous state (package).
 | |
|                  */
 | |
|                 AcpiUtDeleteGenericState (State);
 | |
|                 State = AcpiUtPopGenericState (&StateList);
 | |
| 
 | |
|                 /* Finished when there are no more states */
 | |
| 
 | |
|                 if (!State)
 | |
|                 {
 | |
|                     /*
 | |
|                      * We have handled all of the objects in the top level
 | |
|                      * package just add the length of the package objects
 | |
|                      * and exit
 | |
|                      */
 | |
|                     return_ACPI_STATUS (AE_OK);
 | |
|                 }
 | |
| 
 | |
|                 /*
 | |
|                  * Go back up a level and move the index past the just
 | |
|                  * completed package object.
 | |
|                  */
 | |
|                 State->Pkg.Index++;
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             /* This is a subobject of type package */
 | |
| 
 | |
|             Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
 | |
|                                         State, Context);
 | |
|             if (ACPI_FAILURE (Status))
 | |
|             {
 | |
|                 return_ACPI_STATUS (Status);
 | |
|             }
 | |
| 
 | |
|             /*
 | |
|              * Push the current state and create a new one
 | |
|              * The callback above returned a new target package object.
 | |
|              */
 | |
|             AcpiUtPushGenericState (&StateList, State);
 | |
|             State = AcpiUtCreatePkgState (ThisSourceObj,
 | |
|                                             State->Pkg.ThisTargetObj, 0);
 | |
|             if (!State)
 | |
|             {
 | |
|                 /* Free any stacked Update State objects */
 | |
| 
 | |
|                 while (StateList)
 | |
|                 {
 | |
|                     State = AcpiUtPopGenericState (&StateList);
 | |
|                     AcpiUtDeleteGenericState (State);
 | |
|                 }
 | |
|                 return_ACPI_STATUS (AE_NO_MEMORY);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* We should never get here */
 | |
| 
 | |
|     return_ACPI_STATUS (AE_AML_INTERNAL);
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifdef ACPI_DEBUG_OUTPUT
 | |
| /*******************************************************************************
 | |
|  *
 | |
|  * FUNCTION:    AcpiUtDisplayInitPathname
 | |
|  *
 | |
|  * PARAMETERS:  Type                - Object type of the node
 | |
|  *              ObjHandle           - Handle whose pathname will be displayed
 | |
|  *              Path                - Additional path string to be appended.
 | |
|  *                                      (NULL if no extra path)
 | |
|  *
 | |
|  * RETURN:      ACPI_STATUS
 | |
|  *
 | |
|  * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
 | |
|  *
 | |
|  ******************************************************************************/
 | |
| 
 | |
| void
 | |
| AcpiUtDisplayInitPathname (
 | |
|     UINT8                   Type,
 | |
|     ACPI_NAMESPACE_NODE     *ObjHandle,
 | |
|     char                    *Path)
 | |
| {
 | |
|     ACPI_STATUS             Status;
 | |
|     ACPI_BUFFER             Buffer;
 | |
| 
 | |
| 
 | |
|     ACPI_FUNCTION_ENTRY ();
 | |
| 
 | |
| 
 | |
|     /* Only print the path if the appropriate debug level is enabled */
 | |
| 
 | |
|     if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     /* Get the full pathname to the node */
 | |
| 
 | |
|     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
 | |
|     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
 | |
|     if (ACPI_FAILURE (Status))
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     /* Print what we're doing */
 | |
| 
 | |
|     switch (Type)
 | |
|     {
 | |
|     case ACPI_TYPE_METHOD:
 | |
| 
 | |
|         AcpiOsPrintf ("Executing    ");
 | |
|         break;
 | |
| 
 | |
|     default:
 | |
| 
 | |
|         AcpiOsPrintf ("Initializing ");
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     /* Print the object type and pathname */
 | |
| 
 | |
|     AcpiOsPrintf ("%-12s  %s",
 | |
|         AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
 | |
| 
 | |
|     /* Extra path is used to append names like _STA, _INI, etc. */
 | |
| 
 | |
|     if (Path)
 | |
|     {
 | |
|         AcpiOsPrintf (".%s", Path);
 | |
|     }
 | |
|     AcpiOsPrintf ("\n");
 | |
| 
 | |
|     ACPI_FREE (Buffer.Pointer);
 | |
| }
 | |
| #endif
 | 
