1 /*******************************************************************************
   2  *
   3  * Module Name: utmisc - common utility procedures
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 
  45 #define __UTMISC_C__
  46 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 #include "acnamesp.h"
  50 
  51 
  52 #define _COMPONENT          ACPI_UTILITIES
  53         ACPI_MODULE_NAME    ("utmisc")
  54 
  55 
  56 /*******************************************************************************
  57  *
  58  * FUNCTION:    AcpiUtIsPciRootBridge
  59  *
  60  * PARAMETERS:  Id              - The HID/CID in string format
  61  *
  62  * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
  63  *
  64  * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
  65  *
  66  ******************************************************************************/
  67 
  68 BOOLEAN
  69 AcpiUtIsPciRootBridge (
  70     char                    *Id)
  71 {
  72 
  73     /*
  74      * Check if this is a PCI root bridge.
  75      * ACPI 3.0+: check for a PCI Express root also.
  76      */
  77     if (!(ACPI_STRCMP (Id,
  78             PCI_ROOT_HID_STRING)) ||
  79 
  80         !(ACPI_STRCMP (Id,
  81             PCI_EXPRESS_ROOT_HID_STRING)))
  82     {
  83         return (TRUE);
  84     }
  85 
  86     return (FALSE);
  87 }
  88 
  89 
  90 /*******************************************************************************
  91  *
  92  * FUNCTION:    AcpiUtIsAmlTable
  93  *
  94  * PARAMETERS:  Table               - An ACPI table
  95  *
  96  * RETURN:      TRUE if table contains executable AML; FALSE otherwise
  97  *
  98  * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
  99  *              Currently, these are DSDT,SSDT,PSDT. All other table types are
 100  *              data tables that do not contain AML code.
 101  *
 102  ******************************************************************************/
 103 
 104 BOOLEAN
 105 AcpiUtIsAmlTable (
 106     ACPI_TABLE_HEADER       *Table)
 107 {
 108 
 109     /* These are the only tables that contain executable AML */
 110 
 111     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
 112         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
 113         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
 114     {
 115         return (TRUE);
 116     }
 117 
 118     return (FALSE);
 119 }
 120 
 121 
 122 /*******************************************************************************
 123  *
 124  * FUNCTION:    AcpiUtDwordByteSwap
 125  *
 126  * PARAMETERS:  Value           - Value to be converted
 127  *
 128  * RETURN:      UINT32 integer with bytes swapped
 129  *
 130  * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
 131  *
 132  ******************************************************************************/
 133 
 134 UINT32
 135 AcpiUtDwordByteSwap (
 136     UINT32                  Value)
 137 {
 138     union
 139     {
 140         UINT32              Value;
 141         UINT8               Bytes[4];
 142     } Out;
 143     union
 144     {
 145         UINT32              Value;
 146         UINT8               Bytes[4];
 147     } In;
 148 
 149 
 150     ACPI_FUNCTION_ENTRY ();
 151 
 152 
 153     In.Value = Value;
 154 
 155     Out.Bytes[0] = In.Bytes[3];
 156     Out.Bytes[1] = In.Bytes[2];
 157     Out.Bytes[2] = In.Bytes[1];
 158     Out.Bytes[3] = In.Bytes[0];
 159 
 160     return (Out.Value);
 161 }
 162 
 163 
 164 /*******************************************************************************
 165  *
 166  * FUNCTION:    AcpiUtSetIntegerWidth
 167  *
 168  * PARAMETERS:  Revision            From DSDT header
 169  *
 170  * RETURN:      None
 171  *
 172  * DESCRIPTION: Set the global integer bit width based upon the revision
 173  *              of the DSDT. For Revision 1 and 0, Integers are 32 bits.
 174  *              For Revision 2 and above, Integers are 64 bits. Yes, this
 175  *              makes a difference.
 176  *
 177  ******************************************************************************/
 178 
 179 void
 180 AcpiUtSetIntegerWidth (
 181     UINT8                   Revision)
 182 {
 183 
 184     if (Revision < 2)
 185     {
 186         /* 32-bit case */
 187 
 188         AcpiGbl_IntegerBitWidth    = 32;
 189         AcpiGbl_IntegerNybbleWidth = 8;
 190         AcpiGbl_IntegerByteWidth   = 4;
 191     }
 192     else
 193     {
 194         /* 64-bit case (ACPI 2.0+) */
 195 
 196         AcpiGbl_IntegerBitWidth    = 64;
 197         AcpiGbl_IntegerNybbleWidth = 16;
 198         AcpiGbl_IntegerByteWidth   = 8;
 199     }
 200 }
 201 
 202 
 203 /*******************************************************************************
 204  *
 205  * FUNCTION:    AcpiUtCreateUpdateStateAndPush
 206  *
 207  * PARAMETERS:  Object          - Object to be added to the new state
 208  *              Action          - Increment/Decrement
 209  *              StateList       - List the state will be added to
 210  *
 211  * RETURN:      Status
 212  *
 213  * DESCRIPTION: Create a new state and push it
 214  *
 215  ******************************************************************************/
 216 
 217 ACPI_STATUS
 218 AcpiUtCreateUpdateStateAndPush (
 219     ACPI_OPERAND_OBJECT     *Object,
 220     UINT16                  Action,
 221     ACPI_GENERIC_STATE      **StateList)
 222 {
 223     ACPI_GENERIC_STATE       *State;
 224 
 225 
 226     ACPI_FUNCTION_ENTRY ();
 227 
 228 
 229     /* Ignore null objects; these are expected */
 230 
 231     if (!Object)
 232     {
 233         return (AE_OK);
 234     }
 235 
 236     State = AcpiUtCreateUpdateState (Object, Action);
 237     if (!State)
 238     {
 239         return (AE_NO_MEMORY);
 240     }
 241 
 242     AcpiUtPushGenericState (StateList, State);
 243     return (AE_OK);
 244 }
 245 
 246 
 247 /*******************************************************************************
 248  *
 249  * FUNCTION:    AcpiUtWalkPackageTree
 250  *
 251  * PARAMETERS:  SourceObject        - The package to walk
 252  *              TargetObject        - Target object (if package is being copied)
 253  *              WalkCallback        - Called once for each package element
 254  *              Context             - Passed to the callback function
 255  *
 256  * RETURN:      Status
 257  *
 258  * DESCRIPTION: Walk through a package
 259  *
 260  ******************************************************************************/
 261 
 262 ACPI_STATUS
 263 AcpiUtWalkPackageTree (
 264     ACPI_OPERAND_OBJECT     *SourceObject,
 265     void                    *TargetObject,
 266     ACPI_PKG_CALLBACK       WalkCallback,
 267     void                    *Context)
 268 {
 269     ACPI_STATUS             Status = AE_OK;
 270     ACPI_GENERIC_STATE      *StateList = NULL;
 271     ACPI_GENERIC_STATE      *State;
 272     UINT32                  ThisIndex;
 273     ACPI_OPERAND_OBJECT     *ThisSourceObj;
 274 
 275 
 276     ACPI_FUNCTION_TRACE (UtWalkPackageTree);
 277 
 278 
 279     State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
 280     if (!State)
 281     {
 282         return_ACPI_STATUS (AE_NO_MEMORY);
 283     }
 284 
 285     while (State)
 286     {
 287         /* Get one element of the package */
 288 
 289         ThisIndex     = State->Pkg.Index;
 290         ThisSourceObj = (ACPI_OPERAND_OBJECT *)
 291                         State->Pkg.SourceObject->Package.Elements[ThisIndex];
 292 
 293         /*
 294          * Check for:
 295          * 1) An uninitialized package element. It is completely
 296          *    legal to declare a package and leave it uninitialized
 297          * 2) Not an internal object - can be a namespace node instead
 298          * 3) Any type other than a package. Packages are handled in else
 299          *    case below.
 300          */
 301         if ((!ThisSourceObj) ||
 302             (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
 303             (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
 304         {
 305             Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
 306                                     State, Context);
 307             if (ACPI_FAILURE (Status))
 308             {
 309                 return_ACPI_STATUS (Status);
 310             }
 311 
 312             State->Pkg.Index++;
 313             while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
 314             {
 315                 /*
 316                  * We've handled all of the objects at this level,  This means
 317                  * that we have just completed a package. That package may
 318                  * have contained one or more packages itself.
 319                  *
 320                  * Delete this state and pop the previous state (package).
 321                  */
 322                 AcpiUtDeleteGenericState (State);
 323                 State = AcpiUtPopGenericState (&StateList);
 324 
 325                 /* Finished when there are no more states */
 326 
 327                 if (!State)
 328                 {
 329                     /*
 330                      * We have handled all of the objects in the top level
 331                      * package just add the length of the package objects
 332                      * and exit
 333                      */
 334                     return_ACPI_STATUS (AE_OK);
 335                 }
 336 
 337                 /*
 338                  * Go back up a level and move the index past the just
 339                  * completed package object.
 340                  */
 341                 State->Pkg.Index++;
 342             }
 343         }
 344         else
 345         {
 346             /* This is a subobject of type package */
 347 
 348             Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
 349                                         State, Context);
 350             if (ACPI_FAILURE (Status))
 351             {
 352                 return_ACPI_STATUS (Status);
 353             }
 354 
 355             /*
 356              * Push the current state and create a new one
 357              * The callback above returned a new target package object.
 358              */
 359             AcpiUtPushGenericState (&StateList, State);
 360             State = AcpiUtCreatePkgState (ThisSourceObj,
 361                                             State->Pkg.ThisTargetObj, 0);
 362             if (!State)
 363             {
 364                 /* Free any stacked Update State objects */
 365 
 366                 while (StateList)
 367                 {
 368                     State = AcpiUtPopGenericState (&StateList);
 369                     AcpiUtDeleteGenericState (State);
 370                 }
 371                 return_ACPI_STATUS (AE_NO_MEMORY);
 372             }
 373         }
 374     }
 375 
 376     /* We should never get here */
 377 
 378     return_ACPI_STATUS (AE_AML_INTERNAL);
 379 }
 380 
 381 
 382 #ifdef ACPI_DEBUG_OUTPUT
 383 /*******************************************************************************
 384  *
 385  * FUNCTION:    AcpiUtDisplayInitPathname
 386  *
 387  * PARAMETERS:  Type                - Object type of the node
 388  *              ObjHandle           - Handle whose pathname will be displayed
 389  *              Path                - Additional path string to be appended.
 390  *                                      (NULL if no extra path)
 391  *
 392  * RETURN:      ACPI_STATUS
 393  *
 394  * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
 395  *
 396  ******************************************************************************/
 397 
 398 void
 399 AcpiUtDisplayInitPathname (
 400     UINT8                   Type,
 401     ACPI_NAMESPACE_NODE     *ObjHandle,
 402     char                    *Path)
 403 {
 404     ACPI_STATUS             Status;
 405     ACPI_BUFFER             Buffer;
 406 
 407 
 408     ACPI_FUNCTION_ENTRY ();
 409 
 410 
 411     /* Only print the path if the appropriate debug level is enabled */
 412 
 413     if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
 414     {
 415         return;
 416     }
 417 
 418     /* Get the full pathname to the node */
 419 
 420     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
 421     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
 422     if (ACPI_FAILURE (Status))
 423     {
 424         return;
 425     }
 426 
 427     /* Print what we're doing */
 428 
 429     switch (Type)
 430     {
 431     case ACPI_TYPE_METHOD:
 432 
 433         AcpiOsPrintf ("Executing    ");
 434         break;
 435 
 436     default:
 437 
 438         AcpiOsPrintf ("Initializing ");
 439         break;
 440     }
 441 
 442     /* Print the object type and pathname */
 443 
 444     AcpiOsPrintf ("%-12s  %s",
 445         AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
 446 
 447     /* Extra path is used to append names like _STA, _INI, etc. */
 448 
 449     if (Path)
 450     {
 451         AcpiOsPrintf (".%s", Path);
 452     }
 453     AcpiOsPrintf ("\n");
 454 
 455     ACPI_FREE (Buffer.Pointer);
 456 }
 457 #endif