Home | History | Annotate | Line # | Download | only in debugger
dbnames.c revision 1.11
      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.Count = 0;
    418         Info.OwnerId = ACPI_OWNER_ID_MAX;
    419         Info.DebugLevel = ACPI_UINT32_MAX;
    420         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    421 
    422         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
    423         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
    424         ACPI_FREE (Buffer.Pointer);
    425     }
    426 
    427     return (AE_OK);
    428 }
    429 
    430 
    431 /*******************************************************************************
    432  *
    433  * FUNCTION:    AcpiDbFindNameInNamespace
    434  *
    435  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
    436  *                                wildcards are supported.
    437  *
    438  * RETURN:      None
    439  *
    440  * DESCRIPTION: Search the namespace for a given name (with wildcards)
    441  *
    442  ******************************************************************************/
    443 
    444 ACPI_STATUS
    445 AcpiDbFindNameInNamespace (
    446     char                    *NameArg)
    447 {
    448     char                    AcpiName[5] = "____";
    449     char                    *AcpiNamePtr = AcpiName;
    450 
    451 
    452     if (strlen (NameArg) > ACPI_NAME_SIZE)
    453     {
    454         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
    455         return (AE_OK);
    456     }
    457 
    458     /* Pad out name with underscores as necessary to create a 4-char name */
    459 
    460     AcpiUtStrupr (NameArg);
    461     while (*NameArg)
    462     {
    463         *AcpiNamePtr = *NameArg;
    464         AcpiNamePtr++;
    465         NameArg++;
    466     }
    467 
    468     /* Walk the namespace from the root */
    469 
    470     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    471         ACPI_UINT32_MAX, AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
    472 
    473     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
    474     return (AE_OK);
    475 }
    476 
    477 
    478 /*******************************************************************************
    479  *
    480  * FUNCTION:    AcpiDbWalkForPredefinedNames
    481  *
    482  * PARAMETERS:  Callback from WalkNamespace
    483  *
    484  * RETURN:      Status
    485  *
    486  * DESCRIPTION: Detect and display predefined ACPI names (names that start with
    487  *              an underscore)
    488  *
    489  ******************************************************************************/
    490 
    491 static ACPI_STATUS
    492 AcpiDbWalkForPredefinedNames (
    493     ACPI_HANDLE             ObjHandle,
    494     UINT32                  NestingLevel,
    495     void                    *Context,
    496     void                    **ReturnValue)
    497 {
    498     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    499     UINT32                      *Count = (UINT32 *) Context;
    500     const ACPI_PREDEFINED_INFO  *Predefined;
    501     const ACPI_PREDEFINED_INFO  *Package = NULL;
    502     char                        *Pathname;
    503     char                        StringBuffer[48];
    504 
    505 
    506     Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
    507     if (!Predefined)
    508     {
    509         return (AE_OK);
    510     }
    511 
    512     Pathname = AcpiNsGetNormalizedPathname (Node, TRUE);
    513     if (!Pathname)
    514     {
    515         return (AE_OK);
    516     }
    517 
    518     /* If method returns a package, the info is in the next table entry */
    519 
    520     if (Predefined->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
    521     {
    522         Package = Predefined + 1;
    523     }
    524 
    525     AcpiUtGetExpectedReturnTypes (StringBuffer,
    526         Predefined->Info.ExpectedBtypes);
    527 
    528     AcpiOsPrintf ("%-32s Arguments %X, Return Types: %s", Pathname,
    529         METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList),
    530         StringBuffer);
    531 
    532     if (Package)
    533     {
    534         AcpiOsPrintf (" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
    535             Package->RetInfo.Type, Package->RetInfo.ObjectType1,
    536             Package->RetInfo.Count1);
    537     }
    538 
    539     AcpiOsPrintf("\n");
    540 
    541     /* Check that the declared argument count matches the ACPI spec */
    542 
    543     AcpiNsCheckAcpiCompliance (Pathname, Node, Predefined);
    544 
    545     ACPI_FREE (Pathname);
    546     (*Count)++;
    547     return (AE_OK);
    548 }
    549 
    550 
    551 /*******************************************************************************
    552  *
    553  * FUNCTION:    AcpiDbCheckPredefinedNames
    554  *
    555  * PARAMETERS:  None
    556  *
    557  * RETURN:      None
    558  *
    559  * DESCRIPTION: Validate all predefined names in the namespace
    560  *
    561  ******************************************************************************/
    562 
    563 void
    564 AcpiDbCheckPredefinedNames (
    565     void)
    566 {
    567     UINT32                  Count = 0;
    568 
    569 
    570     /* Search all nodes in namespace */
    571 
    572     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    573         ACPI_UINT32_MAX, AcpiDbWalkForPredefinedNames,
    574         NULL, (void *) &Count, NULL);
    575 
    576     AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
    577 }
    578 
    579 
    580 /*******************************************************************************
    581  *
    582  * FUNCTION:    AcpiDbWalkForObjectCounts
    583  *
    584  * PARAMETERS:  Callback from WalkNamespace
    585  *
    586  * RETURN:      Status
    587  *
    588  * DESCRIPTION: Display short info about objects in the namespace
    589  *
    590  ******************************************************************************/
    591 
    592 static ACPI_STATUS
    593 AcpiDbWalkForObjectCounts (
    594     ACPI_HANDLE             ObjHandle,
    595     UINT32                  NestingLevel,
    596     void                    *Context,
    597     void                    **ReturnValue)
    598 {
    599     ACPI_OBJECT_INFO        *Info = (ACPI_OBJECT_INFO *) Context;
    600     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    601 
    602 
    603     if (Node->Type > ACPI_TYPE_NS_NODE_MAX)
    604     {
    605         AcpiOsPrintf ("[%4.4s]: Unknown object type %X\n",
    606             Node->Name.Ascii, Node->Type);
    607     }
    608     else
    609     {
    610         Info->Types[Node->Type]++;
    611     }
    612 
    613     return (AE_OK);
    614 }
    615 
    616 
    617 /*******************************************************************************
    618  *
    619  * FUNCTION:    AcpiDbWalkForSpecificObjects
    620  *
    621  * PARAMETERS:  Callback from WalkNamespace
    622  *
    623  * RETURN:      Status
    624  *
    625  * DESCRIPTION: Display short info about objects in the namespace
    626  *
    627  ******************************************************************************/
    628 
    629 static ACPI_STATUS
    630 AcpiDbWalkForSpecificObjects (
    631     ACPI_HANDLE             ObjHandle,
    632     UINT32                  NestingLevel,
    633     void                    *Context,
    634     void                    **ReturnValue)
    635 {
    636     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
    637     ACPI_BUFFER             Buffer;
    638     ACPI_STATUS             Status;
    639 
    640 
    641     Info->Count++;
    642 
    643     /* Get and display the full pathname to this object */
    644 
    645     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    646     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
    647     if (ACPI_FAILURE (Status))
    648     {
    649         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
    650         return (AE_OK);
    651     }
    652 
    653     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
    654     ACPI_FREE (Buffer.Pointer);
    655 
    656     /* Dump short info about the object */
    657 
    658     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
    659     return (AE_OK);
    660 }
    661 
    662 
    663 /*******************************************************************************
    664  *
    665  * FUNCTION:    AcpiDbDisplayObjects
    666  *
    667  * PARAMETERS:  ObjTypeArg          - Type of object to display
    668  *              DisplayCountArg     - Max depth to display
    669  *
    670  * RETURN:      None
    671  *
    672  * DESCRIPTION: Display objects in the namespace of the requested type
    673  *
    674  ******************************************************************************/
    675 
    676 ACPI_STATUS
    677 AcpiDbDisplayObjects (
    678     char                    *ObjTypeArg,
    679     char                    *DisplayCountArg)
    680 {
    681     ACPI_WALK_INFO          Info;
    682     ACPI_OBJECT_TYPE        Type;
    683     ACPI_OBJECT_INFO        *ObjectInfo;
    684     UINT32                  i;
    685     UINT32                  TotalObjects = 0;
    686 
    687 
    688     /* No argument means display summary/count of all object types */
    689 
    690     if (!ObjTypeArg)
    691     {
    692         ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO));
    693 
    694         /* Walk the namespace from the root */
    695 
    696         (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    697             ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL,
    698             (void *) ObjectInfo, NULL);
    699 
    700         AcpiOsPrintf ("\nSummary of namespace objects:\n\n");
    701 
    702         for (i = 0; i < ACPI_TOTAL_TYPES; i++)
    703         {
    704             AcpiOsPrintf ("%8u   %s\n", ObjectInfo->Types[i],
    705                 AcpiUtGetTypeName (i));
    706 
    707             TotalObjects += ObjectInfo->Types[i];
    708         }
    709 
    710         AcpiOsPrintf ("\n%8u   Total namespace objects\n\n",
    711             TotalObjects);
    712 
    713         ACPI_FREE (ObjectInfo);
    714         return (AE_OK);
    715     }
    716 
    717     /* Get the object type */
    718 
    719     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
    720     if (Type == ACPI_TYPE_NOT_FOUND)
    721     {
    722         AcpiOsPrintf ("Invalid or unsupported argument\n");
    723         return (AE_OK);
    724     }
    725 
    726     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
    727     AcpiOsPrintf (
    728         "Objects of type [%s] defined in the current ACPI Namespace:\n",
    729         AcpiUtGetTypeName (Type));
    730 
    731     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
    732 
    733     Info.Count = 0;
    734     Info.OwnerId = ACPI_OWNER_ID_MAX;
    735     Info.DebugLevel = ACPI_UINT32_MAX;
    736     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    737 
    738     /* Walk the namespace from the root */
    739 
    740     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
    741         AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
    742 
    743     AcpiOsPrintf (
    744         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
    745         Info.Count, AcpiUtGetTypeName (Type));
    746 
    747     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
    748     return (AE_OK);
    749 }
    750 
    751 
    752 /*******************************************************************************
    753  *
    754  * FUNCTION:    AcpiDbIntegrityWalk
    755  *
    756  * PARAMETERS:  Callback from WalkNamespace
    757  *
    758  * RETURN:      Status
    759  *
    760  * DESCRIPTION: Examine one NS node for valid values.
    761  *
    762  ******************************************************************************/
    763 
    764 static ACPI_STATUS
    765 AcpiDbIntegrityWalk (
    766     ACPI_HANDLE             ObjHandle,
    767     UINT32                  NestingLevel,
    768     void                    *Context,
    769     void                    **ReturnValue)
    770 {
    771     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
    772     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    773     ACPI_OPERAND_OBJECT     *Object;
    774     BOOLEAN                 Alias = TRUE;
    775 
    776 
    777     Info->Nodes++;
    778 
    779     /* Verify the NS node, and dereference aliases */
    780 
    781     while (Alias)
    782     {
    783         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
    784         {
    785             AcpiOsPrintf (
    786                 "Invalid Descriptor Type for Node %p [%s] - "
    787                 "is %2.2X should be %2.2X\n",
    788                 Node, AcpiUtGetDescriptorName (Node),
    789                 ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED);
    790             return (AE_OK);
    791         }
    792 
    793         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
    794             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
    795         {
    796             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
    797         }
    798         else
    799         {
    800             Alias = FALSE;
    801         }
    802     }
    803 
    804     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
    805     {
    806         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
    807             Node, Node->Type);
    808         return (AE_OK);
    809     }
    810 
    811     if (!AcpiUtValidNameseg (Node->Name.Ascii))
    812     {
    813         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
    814         return (AE_OK);
    815     }
    816 
    817     Object = AcpiNsGetAttachedObject (Node);
    818     if (Object)
    819     {
    820         Info->Objects++;
    821         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
    822         {
    823             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
    824                 Object, AcpiUtGetDescriptorName (Object));
    825         }
    826     }
    827 
    828     return (AE_OK);
    829 }
    830 
    831 
    832 /*******************************************************************************
    833  *
    834  * FUNCTION:    AcpiDbCheckIntegrity
    835  *
    836  * PARAMETERS:  None
    837  *
    838  * RETURN:      None
    839  *
    840  * DESCRIPTION: Check entire namespace for data structure integrity
    841  *
    842  ******************************************************************************/
    843 
    844 void
    845 AcpiDbCheckIntegrity (
    846     void)
    847 {
    848     ACPI_INTEGRITY_INFO     Info = {0,0};
    849 
    850     /* Search all nodes in namespace */
    851 
    852     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    853         ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
    854 
    855     AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
    856         Info.Nodes, Info.Objects);
    857 }
    858 
    859 
    860 /*******************************************************************************
    861  *
    862  * FUNCTION:    AcpiDbWalkForReferences
    863  *
    864  * PARAMETERS:  Callback from WalkNamespace
    865  *
    866  * RETURN:      Status
    867  *
    868  * DESCRIPTION: Check if this namespace object refers to the target object
    869  *              that is passed in as the context value.
    870  *
    871  * Note: Currently doesn't check subobjects within the Node's object
    872  *
    873  ******************************************************************************/
    874 
    875 static ACPI_STATUS
    876 AcpiDbWalkForReferences (
    877     ACPI_HANDLE             ObjHandle,
    878     UINT32                  NestingLevel,
    879     void                    *Context,
    880     void                    **ReturnValue)
    881 {
    882     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
    883     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    884 
    885 
    886     /* Check for match against the namespace node itself */
    887 
    888     if (Node == (void *) ObjDesc)
    889     {
    890         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
    891             AcpiUtGetNodeName (Node));
    892     }
    893 
    894     /* Check for match against the object attached to the node */
    895 
    896     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
    897     {
    898         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
    899             Node, AcpiUtGetNodeName (Node));
    900     }
    901 
    902     return (AE_OK);
    903 }
    904 
    905 
    906 /*******************************************************************************
    907  *
    908  * FUNCTION:    AcpiDbFindReferences
    909  *
    910  * PARAMETERS:  ObjectArg       - String with hex value of the object
    911  *
    912  * RETURN:      None
    913  *
    914  * DESCRIPTION: Search namespace for all references to the input object
    915  *
    916  ******************************************************************************/
    917 
    918 void
    919 AcpiDbFindReferences (
    920     char                    *ObjectArg)
    921 {
    922     ACPI_OPERAND_OBJECT     *ObjDesc;
    923     ACPI_SIZE               Address;
    924 
    925 
    926     /* Convert string to object pointer */
    927 
    928     Address = strtoul (ObjectArg, NULL, 16);
    929     ObjDesc = ACPI_TO_POINTER (Address);
    930 
    931     /* Search all nodes in namespace */
    932 
    933     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    934         ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL,
    935         (void *) ObjDesc, NULL);
    936 }
    937 
    938 
    939 /*******************************************************************************
    940  *
    941  * FUNCTION:    AcpiDbBusWalk
    942  *
    943  * PARAMETERS:  Callback from WalkNamespace
    944  *
    945  * RETURN:      Status
    946  *
    947  * DESCRIPTION: Display info about device objects that have a corresponding
    948  *              _PRT method.
    949  *
    950  ******************************************************************************/
    951 
    952 static ACPI_STATUS
    953 AcpiDbBusWalk (
    954     ACPI_HANDLE             ObjHandle,
    955     UINT32                  NestingLevel,
    956     void                    *Context,
    957     void                    **ReturnValue)
    958 {
    959     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    960     ACPI_STATUS             Status;
    961     ACPI_BUFFER             Buffer;
    962     ACPI_NAMESPACE_NODE     *TempNode;
    963     ACPI_DEVICE_INFO        *Info;
    964     UINT32                  i;
    965 
    966 
    967     if ((Node->Type != ACPI_TYPE_DEVICE) &&
    968         (Node->Type != ACPI_TYPE_PROCESSOR))
    969     {
    970         return (AE_OK);
    971     }
    972 
    973     /* Exit if there is no _PRT under this device */
    974 
    975     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
    976         ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
    977     if (ACPI_FAILURE (Status))
    978     {
    979         return (AE_OK);
    980     }
    981 
    982     /* Get the full path to this device object */
    983 
    984     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    985     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
    986     if (ACPI_FAILURE (Status))
    987     {
    988         AcpiOsPrintf ("Could Not get pathname for object %p\n",
    989             ObjHandle);
    990         return (AE_OK);
    991     }
    992 
    993     Status = AcpiGetObjectInfo (ObjHandle, &Info);
    994     if (ACPI_FAILURE (Status))
    995     {
    996         return (AE_OK);
    997     }
    998 
    999     /* Display the full path */
   1000 
   1001     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
   1002     ACPI_FREE (Buffer.Pointer);
   1003 
   1004     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
   1005     {
   1006         AcpiOsPrintf ("  - Is PCI Root Bridge");
   1007     }
   1008     AcpiOsPrintf ("\n");
   1009 
   1010     /* _PRT info */
   1011 
   1012     AcpiOsPrintf ("_PRT: %p\n", TempNode);
   1013 
   1014     /* Dump _ADR, _HID, _UID, _CID */
   1015 
   1016     if (Info->Valid & ACPI_VALID_ADR)
   1017     {
   1018         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n",
   1019             ACPI_FORMAT_UINT64 (Info->Address));
   1020     }
   1021     else
   1022     {
   1023         AcpiOsPrintf ("_ADR: <Not Present>\n");
   1024     }
   1025 
   1026     if (Info->Valid & ACPI_VALID_HID)
   1027     {
   1028         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
   1029     }
   1030     else
   1031     {
   1032         AcpiOsPrintf ("_HID: <Not Present>\n");
   1033     }
   1034 
   1035     if (Info->Valid & ACPI_VALID_UID)
   1036     {
   1037         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
   1038     }
   1039     else
   1040     {
   1041         AcpiOsPrintf ("_UID: <Not Present>\n");
   1042     }
   1043 
   1044     if (Info->Valid & ACPI_VALID_CID)
   1045     {
   1046         for (i = 0; i < Info->CompatibleIdList.Count; i++)
   1047         {
   1048             AcpiOsPrintf ("_CID: %s\n",
   1049                 Info->CompatibleIdList.Ids[i].String);
   1050         }
   1051     }
   1052     else
   1053     {
   1054         AcpiOsPrintf ("_CID: <Not Present>\n");
   1055     }
   1056 
   1057     ACPI_FREE (Info);
   1058     return (AE_OK);
   1059 }
   1060 
   1061 
   1062 /*******************************************************************************
   1063  *
   1064  * FUNCTION:    AcpiDbGetBusInfo
   1065  *
   1066  * PARAMETERS:  None
   1067  *
   1068  * RETURN:      None
   1069  *
   1070  * DESCRIPTION: Display info about system busses.
   1071  *
   1072  ******************************************************************************/
   1073 
   1074 void
   1075 AcpiDbGetBusInfo (
   1076     void)
   1077 {
   1078     /* Search all nodes in namespace */
   1079 
   1080     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
   1081         ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL);
   1082 }
   1083