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