Home | History | Annotate | Line # | Download | only in debugger
dbnames.c revision 1.10
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbnames - Debugger commands for the acpi namespace
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2018, 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 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acnamesp.h"
     47 #include "acdebug.h"
     48 #include "acpredef.h"
     49 
     50 
     51 #define _COMPONENT          ACPI_CA_DEBUGGER
     52         ACPI_MODULE_NAME    ("dbnames")
     53 
     54 
     55 /* Local prototypes */
     56 
     57 static ACPI_STATUS
     58 AcpiDbWalkAndMatchName (
     59     ACPI_HANDLE             ObjHandle,
     60     UINT32                  NestingLevel,
     61     void                    *Context,
     62     void                    **ReturnValue);
     63 
     64 static ACPI_STATUS
     65 AcpiDbWalkForPredefinedNames (
     66     ACPI_HANDLE             ObjHandle,
     67     UINT32                  NestingLevel,
     68     void                    *Context,
     69     void                    **ReturnValue);
     70 
     71 static ACPI_STATUS
     72 AcpiDbWalkForSpecificObjects (
     73     ACPI_HANDLE             ObjHandle,
     74     UINT32                  NestingLevel,
     75     void                    *Context,
     76     void                    **ReturnValue);
     77 
     78 static ACPI_STATUS
     79 AcpiDbWalkForObjectCounts (
     80     ACPI_HANDLE             ObjHandle,
     81     UINT32                  NestingLevel,
     82     void                    *Context,
     83     void                    **ReturnValue);
     84 
     85 static ACPI_STATUS
     86 AcpiDbIntegrityWalk (
     87     ACPI_HANDLE             ObjHandle,
     88     UINT32                  NestingLevel,
     89     void                    *Context,
     90     void                    **ReturnValue);
     91 
     92 static ACPI_STATUS
     93 AcpiDbWalkForReferences (
     94     ACPI_HANDLE             ObjHandle,
     95     UINT32                  NestingLevel,
     96     void                    *Context,
     97     void                    **ReturnValue);
     98 
     99 static ACPI_STATUS
    100 AcpiDbBusWalk (
    101     ACPI_HANDLE             ObjHandle,
    102     UINT32                  NestingLevel,
    103     void                    *Context,
    104     void                    **ReturnValue);
    105 
    106 /*
    107  * Arguments for the Objects command
    108  * These object types map directly to the ACPI_TYPES
    109  */
    110 static ACPI_DB_ARGUMENT_INFO    AcpiDbObjectTypes [] =
    111 {
    112     {"ANY"},
    113     {"INTEGERS"},
    114     {"STRINGS"},
    115     {"BUFFERS"},
    116     {"PACKAGES"},
    117     {"FIELDS"},
    118     {"DEVICES"},
    119     {"EVENTS"},
    120     {"METHODS"},
    121     {"MUTEXES"},
    122     {"REGIONS"},
    123     {"POWERRESOURCES"},
    124     {"PROCESSORS"},
    125     {"THERMALZONES"},
    126     {"BUFFERFIELDS"},
    127     {"DDBHANDLES"},
    128     {"DEBUG"},
    129     {"REGIONFIELDS"},
    130     {"BANKFIELDS"},
    131     {"INDEXFIELDS"},
    132     {"REFERENCES"},
    133     {"ALIASES"},
    134     {"METHODALIASES"},
    135     {"NOTIFY"},
    136     {"ADDRESSHANDLER"},
    137     {"RESOURCE"},
    138     {"RESOURCEFIELD"},
    139     {"SCOPES"},
    140     {NULL}           /* Must be null terminated */
    141 };
    142 
    143 
    144 /*******************************************************************************
    145  *
    146  * FUNCTION:    AcpiDbSetScope
    147  *
    148  * PARAMETERS:  Name                - New scope path
    149  *
    150  * RETURN:      Status
    151  *
    152  * DESCRIPTION: Set the "current scope" as maintained by this utility.
    153  *              The scope is used as a prefix to ACPI paths.
    154  *
    155  ******************************************************************************/
    156 
    157 void
    158 AcpiDbSetScope (
    159     char                    *Name)
    160 {
    161     ACPI_STATUS             Status;
    162     ACPI_NAMESPACE_NODE     *Node;
    163 
    164 
    165     if (!Name || Name[0] == 0)
    166     {
    167         AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
    168         return;
    169     }
    170 
    171     AcpiDbPrepNamestring (Name);
    172 
    173     if (ACPI_IS_ROOT_PREFIX (Name[0]))
    174     {
    175         /* Validate new scope from the root */
    176 
    177         Status = AcpiNsGetNode (AcpiGbl_RootNode, Name,
    178             ACPI_NS_NO_UPSEARCH, &Node);
    179         if (ACPI_FAILURE (Status))
    180         {
    181             goto ErrorExit;
    182         }
    183 
    184         AcpiGbl_DbScopeBuf[0] = 0;
    185     }
    186     else
    187     {
    188         /* Validate new scope relative to old scope */
    189 
    190         Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name,
    191             ACPI_NS_NO_UPSEARCH, &Node);
    192         if (ACPI_FAILURE (Status))
    193         {
    194             goto ErrorExit;
    195         }
    196     }
    197 
    198     /* Build the final pathname */
    199 
    200     if (AcpiUtSafeStrcat (AcpiGbl_DbScopeBuf, sizeof (AcpiGbl_DbScopeBuf),
    201         Name))
    202     {
    203         Status = AE_BUFFER_OVERFLOW;
    204         goto ErrorExit;
    205     }
    206 
    207     if (AcpiUtSafeStrcat (AcpiGbl_DbScopeBuf, sizeof (AcpiGbl_DbScopeBuf),
    208 	    __UNCONST("\\")))
    209     {
    210         Status = AE_BUFFER_OVERFLOW;
    211         goto ErrorExit;
    212     }
    213 
    214     AcpiGbl_DbScopeNode = Node;
    215     AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
    216     return;
    217 
    218 ErrorExit:
    219 
    220     AcpiOsPrintf ("Could not attach scope: %s, %s\n",
    221         Name, AcpiFormatException (Status));
    222 }
    223 
    224 
    225 /*******************************************************************************
    226  *
    227  * FUNCTION:    AcpiDbDumpNamespace
    228  *
    229  * PARAMETERS:  StartArg        - Node to begin namespace dump
    230  *              DepthArg        - Maximum tree depth to be dumped
    231  *
    232  * RETURN:      None
    233  *
    234  * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
    235  *              with type and other information.
    236  *
    237  ******************************************************************************/
    238 
    239 void
    240 AcpiDbDumpNamespace (
    241     char                    *StartArg,
    242     char                    *DepthArg)
    243 {
    244     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
    245     UINT32                  MaxDepth = ACPI_UINT32_MAX;
    246 
    247 
    248     /* No argument given, just start at the root and dump entire namespace */
    249 
    250     if (StartArg)
    251     {
    252         SubtreeEntry = AcpiDbConvertToNode (StartArg);
    253         if (!SubtreeEntry)
    254         {
    255             return;
    256         }
    257 
    258         /* Now we can check for the depth argument */
    259 
    260         if (DepthArg)
    261         {
    262             MaxDepth = strtoul (DepthArg, NULL, 0);
    263         }
    264     }
    265 
    266     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
    267 
    268     if (((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Parent)
    269     {
    270         AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
    271             ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
    272     }
    273     else
    274     {
    275         AcpiOsPrintf ("ACPI Namespace (from %s):\n",
    276             ACPI_NAMESPACE_ROOT);
    277     }
    278 
    279     /* Display the subtree */
    280 
    281     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
    282     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
    283         ACPI_OWNER_ID_MAX, SubtreeEntry);
    284     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
    285 }
    286 
    287 
    288 /*******************************************************************************
    289  *
    290  * FUNCTION:    AcpiDbDumpNamespacePaths
    291  *
    292  * PARAMETERS:  None
    293  *
    294  * RETURN:      None
    295  *
    296  * DESCRIPTION: Dump entire namespace with full object pathnames and object
    297  *              type information. Alternative to "namespace" command.
    298  *
    299  ******************************************************************************/
    300 
    301 void
    302 AcpiDbDumpNamespacePaths (
    303     void)
    304 {
    305 
    306     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
    307     AcpiOsPrintf ("ACPI Namespace (from root):\n");
    308 
    309     /* Display the entire namespace */
    310 
    311     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
    312     AcpiNsDumpObjectPaths (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
    313         ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX, AcpiGbl_RootNode);
    314 
    315     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
    316 }
    317 
    318 
    319 /*******************************************************************************
    320  *
    321  * FUNCTION:    AcpiDbDumpNamespaceByOwner
    322  *
    323  * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
    324  *              DepthArg        - Maximum tree depth to be dumped
    325  *
    326  * RETURN:      None
    327  *
    328  * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
    329  *
    330  ******************************************************************************/
    331 
    332 void
    333 AcpiDbDumpNamespaceByOwner (
    334     char                    *OwnerArg,
    335     char                    *DepthArg)
    336 {
    337     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
    338     UINT32                  MaxDepth = ACPI_UINT32_MAX;
    339     ACPI_OWNER_ID           OwnerId;
    340 
    341 
    342     OwnerId = (ACPI_OWNER_ID) strtoul (OwnerArg, NULL, 0);
    343 
    344     /* Now we can check for the depth argument */
    345 
    346     if (DepthArg)
    347     {
    348         MaxDepth = strtoul (DepthArg, NULL, 0);
    349     }
    350 
    351     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
    352     AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
    353 
    354     /* Display the subtree */
    355 
    356     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
    357     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
    358         OwnerId, SubtreeEntry);
    359     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
    360 }
    361 
    362 
    363 /*******************************************************************************
    364  *
    365  * FUNCTION:    AcpiDbWalkAndMatchName
    366  *
    367  * PARAMETERS:  Callback from WalkNamespace
    368  *
    369  * RETURN:      Status
    370  *
    371  * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
    372  *              are supported -- '?' matches any character.
    373  *
    374  ******************************************************************************/
    375 
    376 static ACPI_STATUS
    377 AcpiDbWalkAndMatchName (
    378     ACPI_HANDLE             ObjHandle,
    379     UINT32                  NestingLevel,
    380     void                    *Context,
    381     void                    **ReturnValue)
    382 {
    383     ACPI_STATUS             Status;
    384     char                    *RequestedName = (char *) Context;
    385     UINT32                  i;
    386     ACPI_BUFFER             Buffer;
    387     ACPI_WALK_INFO          Info;
    388 
    389 
    390     /* Check for a name match */
    391 
    392     for (i = 0; i < 4; i++)
    393     {
    394         /* Wildcard support */
    395 
    396         if ((RequestedName[i] != '?') &&
    397             (RequestedName[i] != ((ACPI_NAMESPACE_NODE *)
    398                 ObjHandle)->Name.Ascii[i]))
    399         {
    400             /* No match, just exit */
    401 
    402             return (AE_OK);
    403         }
    404     }
    405 
    406     /* Get the full pathname to this object */
    407 
    408     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    409     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
    410     if (ACPI_FAILURE (Status))
    411     {
    412         AcpiOsPrintf ("Could Not get pathname for object %p\n",
    413             ObjHandle);
    414     }
    415     else
    416     {
    417         Info.OwnerId = ACPI_OWNER_ID_MAX;
    418         Info.DebugLevel = ACPI_UINT32_MAX;
    419         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    420 
    421         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
    422         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
    423         ACPI_FREE (Buffer.Pointer);
    424     }
    425 
    426     return (AE_OK);
    427 }
    428 
    429 
    430 /*******************************************************************************
    431  *
    432  * FUNCTION:    AcpiDbFindNameInNamespace
    433  *
    434  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
    435  *                                wildcards are supported.
    436  *
    437  * RETURN:      None
    438  *
    439  * DESCRIPTION: Search the namespace for a given name (with wildcards)
    440  *
    441  ******************************************************************************/
    442 
    443 ACPI_STATUS
    444 AcpiDbFindNameInNamespace (
    445     char                    *NameArg)
    446 {
    447     char                    AcpiName[5] = "____";
    448     char                    *AcpiNamePtr = AcpiName;
    449 
    450 
    451     if (strlen (NameArg) > ACPI_NAME_SIZE)
    452     {
    453         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
    454         return (AE_OK);
    455     }
    456 
    457     /* Pad out name with underscores as necessary to create a 4-char name */
    458 
    459     AcpiUtStrupr (NameArg);
    460     while (*NameArg)
    461     {
    462         *AcpiNamePtr = *NameArg;
    463         AcpiNamePtr++;
    464         NameArg++;
    465     }
    466 
    467     /* Walk the namespace from the root */
    468 
    469     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    470         ACPI_UINT32_MAX, AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
    471 
    472     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
    473     return (AE_OK);
    474 }
    475 
    476 
    477 /*******************************************************************************
    478  *
    479  * FUNCTION:    AcpiDbWalkForPredefinedNames
    480  *
    481  * PARAMETERS:  Callback from WalkNamespace
    482  *
    483  * RETURN:      Status
    484  *
    485  * DESCRIPTION: Detect and display predefined ACPI names (names that start with
    486  *              an underscore)
    487  *
    488  ******************************************************************************/
    489 
    490 static ACPI_STATUS
    491 AcpiDbWalkForPredefinedNames (
    492     ACPI_HANDLE             ObjHandle,
    493     UINT32                  NestingLevel,
    494     void                    *Context,
    495     void                    **ReturnValue)
    496 {
    497     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    498     UINT32                      *Count = (UINT32 *) Context;
    499     const ACPI_PREDEFINED_INFO  *Predefined;
    500     const ACPI_PREDEFINED_INFO  *Package = NULL;
    501     char                        *Pathname;
    502     char                        StringBuffer[48];
    503 
    504 
    505     Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
    506     if (!Predefined)
    507     {
    508         return (AE_OK);
    509     }
    510 
    511     Pathname = AcpiNsGetNormalizedPathname (Node, TRUE);
    512     if (!Pathname)
    513     {
    514         return (AE_OK);
    515     }
    516 
    517     /* If method returns a package, the info is in the next table entry */
    518 
    519     if (Predefined->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
    520     {
    521         Package = Predefined + 1;
    522     }
    523 
    524     AcpiUtGetExpectedReturnTypes (StringBuffer,
    525         Predefined->Info.ExpectedBtypes);
    526 
    527     AcpiOsPrintf ("%-32s Arguments %X, Return Types: %s", Pathname,
    528         METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList),
    529         StringBuffer);
    530 
    531     if (Package)
    532     {
    533         AcpiOsPrintf (" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
    534             Package->RetInfo.Type, Package->RetInfo.ObjectType1,
    535             Package->RetInfo.Count1);
    536     }
    537 
    538     AcpiOsPrintf("\n");
    539 
    540     /* Check that the declared argument count matches the ACPI spec */
    541 
    542     AcpiNsCheckAcpiCompliance (Pathname, Node, Predefined);
    543 
    544     ACPI_FREE (Pathname);
    545     (*Count)++;
    546     return (AE_OK);
    547 }
    548 
    549 
    550 /*******************************************************************************
    551  *
    552  * FUNCTION:    AcpiDbCheckPredefinedNames
    553  *
    554  * PARAMETERS:  None
    555  *
    556  * RETURN:      None
    557  *
    558  * DESCRIPTION: Validate all predefined names in the namespace
    559  *
    560  ******************************************************************************/
    561 
    562 void
    563 AcpiDbCheckPredefinedNames (
    564     void)
    565 {
    566     UINT32                  Count = 0;
    567 
    568 
    569     /* Search all nodes in namespace */
    570 
    571     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    572         ACPI_UINT32_MAX, AcpiDbWalkForPredefinedNames,
    573         NULL, (void *) &Count, NULL);
    574 
    575     AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
    576 }
    577 
    578 
    579 /*******************************************************************************
    580  *
    581  * FUNCTION:    AcpiDbWalkForObjectCounts
    582  *
    583  * PARAMETERS:  Callback from WalkNamespace
    584  *
    585  * RETURN:      Status
    586  *
    587  * DESCRIPTION: Display short info about objects in the namespace
    588  *
    589  ******************************************************************************/
    590 
    591 static ACPI_STATUS
    592 AcpiDbWalkForObjectCounts (
    593     ACPI_HANDLE             ObjHandle,
    594     UINT32                  NestingLevel,
    595     void                    *Context,
    596     void                    **ReturnValue)
    597 {
    598     ACPI_OBJECT_INFO        *Info = (ACPI_OBJECT_INFO *) Context;
    599     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    600 
    601 
    602     if (Node->Type > ACPI_TYPE_NS_NODE_MAX)
    603     {
    604         AcpiOsPrintf ("[%4.4s]: Unknown object type %X\n",
    605             Node->Name.Ascii, Node->Type);
    606     }
    607     else
    608     {
    609         Info->Types[Node->Type]++;
    610     }
    611 
    612     return (AE_OK);
    613 }
    614 
    615 
    616 /*******************************************************************************
    617  *
    618  * FUNCTION:    AcpiDbWalkForSpecificObjects
    619  *
    620  * PARAMETERS:  Callback from WalkNamespace
    621  *
    622  * RETURN:      Status
    623  *
    624  * DESCRIPTION: Display short info about objects in the namespace
    625  *
    626  ******************************************************************************/
    627 
    628 static ACPI_STATUS
    629 AcpiDbWalkForSpecificObjects (
    630     ACPI_HANDLE             ObjHandle,
    631     UINT32                  NestingLevel,
    632     void                    *Context,
    633     void                    **ReturnValue)
    634 {
    635     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
    636     ACPI_BUFFER             Buffer;
    637     ACPI_STATUS             Status;
    638 
    639 
    640     Info->Count++;
    641 
    642     /* Get and display the full pathname to this object */
    643 
    644     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    645     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
    646     if (ACPI_FAILURE (Status))
    647     {
    648         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
    649         return (AE_OK);
    650     }
    651 
    652     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
    653     ACPI_FREE (Buffer.Pointer);
    654 
    655     /* Dump short info about the object */
    656 
    657     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
    658     return (AE_OK);
    659 }
    660 
    661 
    662 /*******************************************************************************
    663  *
    664  * FUNCTION:    AcpiDbDisplayObjects
    665  *
    666  * PARAMETERS:  ObjTypeArg          - Type of object to display
    667  *              DisplayCountArg     - Max depth to display
    668  *
    669  * RETURN:      None
    670  *
    671  * DESCRIPTION: Display objects in the namespace of the requested type
    672  *
    673  ******************************************************************************/
    674 
    675 ACPI_STATUS
    676 AcpiDbDisplayObjects (
    677     char                    *ObjTypeArg,
    678     char                    *DisplayCountArg)
    679 {
    680     ACPI_WALK_INFO          Info;
    681     ACPI_OBJECT_TYPE        Type;
    682     ACPI_OBJECT_INFO        *ObjectInfo;
    683     UINT32                  i;
    684     UINT32                  TotalObjects = 0;
    685 
    686 
    687     /* No argument means display summary/count of all object types */
    688 
    689     if (!ObjTypeArg)
    690     {
    691         ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO));
    692 
    693         /* Walk the namespace from the root */
    694 
    695         (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    696             ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL,
    697             (void *) ObjectInfo, NULL);
    698 
    699         AcpiOsPrintf ("\nSummary of namespace objects:\n\n");
    700 
    701         for (i = 0; i < ACPI_TOTAL_TYPES; i++)
    702         {
    703             AcpiOsPrintf ("%8u   %s\n", ObjectInfo->Types[i],
    704                 AcpiUtGetTypeName (i));
    705 
    706             TotalObjects += ObjectInfo->Types[i];
    707         }
    708 
    709         AcpiOsPrintf ("\n%8u   Total namespace objects\n\n",
    710             TotalObjects);
    711 
    712         ACPI_FREE (ObjectInfo);
    713         return (AE_OK);
    714     }
    715 
    716     /* Get the object type */
    717 
    718     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
    719     if (Type == ACPI_TYPE_NOT_FOUND)
    720     {
    721         AcpiOsPrintf ("Invalid or unsupported argument\n");
    722         return (AE_OK);
    723     }
    724 
    725     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
    726     AcpiOsPrintf (
    727         "Objects of type [%s] defined in the current ACPI Namespace:\n",
    728         AcpiUtGetTypeName (Type));
    729 
    730     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
    731 
    732     Info.Count = 0;
    733     Info.OwnerId = ACPI_OWNER_ID_MAX;
    734     Info.DebugLevel = ACPI_UINT32_MAX;
    735     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    736 
    737     /* Walk the namespace from the root */
    738 
    739     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
    740         AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
    741 
    742     AcpiOsPrintf (
    743         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
    744         Info.Count, AcpiUtGetTypeName (Type));
    745 
    746     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
    747     return (AE_OK);
    748 }
    749 
    750 
    751 /*******************************************************************************
    752  *
    753  * FUNCTION:    AcpiDbIntegrityWalk
    754  *
    755  * PARAMETERS:  Callback from WalkNamespace
    756  *
    757  * RETURN:      Status
    758  *
    759  * DESCRIPTION: Examine one NS node for valid values.
    760  *
    761  ******************************************************************************/
    762 
    763 static ACPI_STATUS
    764 AcpiDbIntegrityWalk (
    765     ACPI_HANDLE             ObjHandle,
    766     UINT32                  NestingLevel,
    767     void                    *Context,
    768     void                    **ReturnValue)
    769 {
    770     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
    771     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    772     ACPI_OPERAND_OBJECT     *Object;
    773     BOOLEAN                 Alias = TRUE;
    774 
    775 
    776     Info->Nodes++;
    777 
    778     /* Verify the NS node, and dereference aliases */
    779 
    780     while (Alias)
    781     {
    782         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
    783         {
    784             AcpiOsPrintf (
    785                 "Invalid Descriptor Type for Node %p [%s] - "
    786                 "is %2.2X should be %2.2X\n",
    787                 Node, AcpiUtGetDescriptorName (Node),
    788                 ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED);
    789             return (AE_OK);
    790         }
    791 
    792         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
    793             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
    794         {
    795             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
    796         }
    797         else
    798         {
    799             Alias = FALSE;
    800         }
    801     }
    802 
    803     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
    804     {
    805         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
    806             Node, Node->Type);
    807         return (AE_OK);
    808     }
    809 
    810     if (!AcpiUtValidNameseg (Node->Name.Ascii))
    811     {
    812         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
    813         return (AE_OK);
    814     }
    815 
    816     Object = AcpiNsGetAttachedObject (Node);
    817     if (Object)
    818     {
    819         Info->Objects++;
    820         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
    821         {
    822             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
    823                 Object, AcpiUtGetDescriptorName (Object));
    824         }
    825     }
    826 
    827     return (AE_OK);
    828 }
    829 
    830 
    831 /*******************************************************************************
    832  *
    833  * FUNCTION:    AcpiDbCheckIntegrity
    834  *
    835  * PARAMETERS:  None
    836  *
    837  * RETURN:      None
    838  *
    839  * DESCRIPTION: Check entire namespace for data structure integrity
    840  *
    841  ******************************************************************************/
    842 
    843 void
    844 AcpiDbCheckIntegrity (
    845     void)
    846 {
    847     ACPI_INTEGRITY_INFO     Info = {0,0};
    848 
    849     /* Search all nodes in namespace */
    850 
    851     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    852         ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
    853 
    854     AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
    855         Info.Nodes, Info.Objects);
    856 }
    857 
    858 
    859 /*******************************************************************************
    860  *
    861  * FUNCTION:    AcpiDbWalkForReferences
    862  *
    863  * PARAMETERS:  Callback from WalkNamespace
    864  *
    865  * RETURN:      Status
    866  *
    867  * DESCRIPTION: Check if this namespace object refers to the target object
    868  *              that is passed in as the context value.
    869  *
    870  * Note: Currently doesn't check subobjects within the Node's object
    871  *
    872  ******************************************************************************/
    873 
    874 static ACPI_STATUS
    875 AcpiDbWalkForReferences (
    876     ACPI_HANDLE             ObjHandle,
    877     UINT32                  NestingLevel,
    878     void                    *Context,
    879     void                    **ReturnValue)
    880 {
    881     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
    882     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    883 
    884 
    885     /* Check for match against the namespace node itself */
    886 
    887     if (Node == (void *) ObjDesc)
    888     {
    889         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
    890             AcpiUtGetNodeName (Node));
    891     }
    892 
    893     /* Check for match against the object attached to the node */
    894 
    895     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
    896     {
    897         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
    898             Node, AcpiUtGetNodeName (Node));
    899     }
    900 
    901     return (AE_OK);
    902 }
    903 
    904 
    905 /*******************************************************************************
    906  *
    907  * FUNCTION:    AcpiDbFindReferences
    908  *
    909  * PARAMETERS:  ObjectArg       - String with hex value of the object
    910  *
    911  * RETURN:      None
    912  *
    913  * DESCRIPTION: Search namespace for all references to the input object
    914  *
    915  ******************************************************************************/
    916 
    917 void
    918 AcpiDbFindReferences (
    919     char                    *ObjectArg)
    920 {
    921     ACPI_OPERAND_OBJECT     *ObjDesc;
    922     ACPI_SIZE               Address;
    923 
    924 
    925     /* Convert string to object pointer */
    926 
    927     Address = strtoul (ObjectArg, NULL, 16);
    928     ObjDesc = ACPI_TO_POINTER (Address);
    929 
    930     /* Search all nodes in namespace */
    931 
    932     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    933         ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL,
    934         (void *) ObjDesc, NULL);
    935 }
    936 
    937 
    938 /*******************************************************************************
    939  *
    940  * FUNCTION:    AcpiDbBusWalk
    941  *
    942  * PARAMETERS:  Callback from WalkNamespace
    943  *
    944  * RETURN:      Status
    945  *
    946  * DESCRIPTION: Display info about device objects that have a corresponding
    947  *              _PRT method.
    948  *
    949  ******************************************************************************/
    950 
    951 static ACPI_STATUS
    952 AcpiDbBusWalk (
    953     ACPI_HANDLE             ObjHandle,
    954     UINT32                  NestingLevel,
    955     void                    *Context,
    956     void                    **ReturnValue)
    957 {
    958     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    959     ACPI_STATUS             Status;
    960     ACPI_BUFFER             Buffer;
    961     ACPI_NAMESPACE_NODE     *TempNode;
    962     ACPI_DEVICE_INFO        *Info;
    963     UINT32                  i;
    964 
    965 
    966     if ((Node->Type != ACPI_TYPE_DEVICE) &&
    967         (Node->Type != ACPI_TYPE_PROCESSOR))
    968     {
    969         return (AE_OK);
    970     }
    971 
    972     /* Exit if there is no _PRT under this device */
    973 
    974     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
    975         ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
    976     if (ACPI_FAILURE (Status))
    977     {
    978         return (AE_OK);
    979     }
    980 
    981     /* Get the full path to this device object */
    982 
    983     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    984     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
    985     if (ACPI_FAILURE (Status))
    986     {
    987         AcpiOsPrintf ("Could Not get pathname for object %p\n",
    988             ObjHandle);
    989         return (AE_OK);
    990     }
    991 
    992     Status = AcpiGetObjectInfo (ObjHandle, &Info);
    993     if (ACPI_FAILURE (Status))
    994     {
    995         return (AE_OK);
    996     }
    997 
    998     /* Display the full path */
    999 
   1000     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
   1001     ACPI_FREE (Buffer.Pointer);
   1002 
   1003     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
   1004     {
   1005         AcpiOsPrintf ("  - Is PCI Root Bridge");
   1006     }
   1007     AcpiOsPrintf ("\n");
   1008 
   1009     /* _PRT info */
   1010 
   1011     AcpiOsPrintf ("_PRT: %p\n", TempNode);
   1012 
   1013     /* Dump _ADR, _HID, _UID, _CID */
   1014 
   1015     if (Info->Valid & ACPI_VALID_ADR)
   1016     {
   1017         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n",
   1018             ACPI_FORMAT_UINT64 (Info->Address));
   1019     }
   1020     else
   1021     {
   1022         AcpiOsPrintf ("_ADR: <Not Present>\n");
   1023     }
   1024 
   1025     if (Info->Valid & ACPI_VALID_HID)
   1026     {
   1027         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
   1028     }
   1029     else
   1030     {
   1031         AcpiOsPrintf ("_HID: <Not Present>\n");
   1032     }
   1033 
   1034     if (Info->Valid & ACPI_VALID_UID)
   1035     {
   1036         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
   1037     }
   1038     else
   1039     {
   1040         AcpiOsPrintf ("_UID: <Not Present>\n");
   1041     }
   1042 
   1043     if (Info->Valid & ACPI_VALID_CID)
   1044     {
   1045         for (i = 0; i < Info->CompatibleIdList.Count; i++)
   1046         {
   1047             AcpiOsPrintf ("_CID: %s\n",
   1048                 Info->CompatibleIdList.Ids[i].String);
   1049         }
   1050     }
   1051     else
   1052     {
   1053         AcpiOsPrintf ("_CID: <Not Present>\n");
   1054     }
   1055 
   1056     ACPI_FREE (Info);
   1057     return (AE_OK);
   1058 }
   1059 
   1060 
   1061 /*******************************************************************************
   1062  *
   1063  * FUNCTION:    AcpiDbGetBusInfo
   1064  *
   1065  * PARAMETERS:  None
   1066  *
   1067  * RETURN:      None
   1068  *
   1069  * DESCRIPTION: Display info about system busses.
   1070  *
   1071  ******************************************************************************/
   1072 
   1073 void
   1074 AcpiDbGetBusInfo (
   1075     void)
   1076 {
   1077     /* Search all nodes in namespace */
   1078 
   1079     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
   1080         ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL);
   1081 }
   1082