Home | History | Annotate | Line # | Download | only in debugger
dbnames.c revision 1.18
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbnames - Debugger commands for the acpi namespace
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2023, 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     Status = AcpiEvaluateObject (ObjHandle, NULL, NULL, &Buffer);
    670     if (ACPI_FAILURE (Status))
    671     {
    672         AcpiOsPrintf ("Could Not evaluate object %p\n", ObjHandle);
    673         return (AE_OK);
    674     }
    675 
    676     /*
    677      * Since this is a field unit, surround the output in braces
    678      */
    679     AcpiOsPrintf ("{");
    680 
    681     RetValue = (ACPI_OBJECT *) Buffer.Pointer;
    682     switch (RetValue->Type)
    683     {
    684         case ACPI_TYPE_INTEGER:
    685 
    686             AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (RetValue->Integer.Value));
    687             break;
    688 
    689         case ACPI_TYPE_BUFFER:
    690 
    691             AcpiUtDumpBuffer (RetValue->Buffer.Pointer,
    692                 RetValue->Buffer.Length, DB_DISPLAY_DATA_ONLY | DB_BYTE_DISPLAY, 0);
    693             break;
    694 
    695         default:
    696 
    697             break;
    698     }
    699 
    700     AcpiOsPrintf ("}\n");
    701 
    702     ACPI_FREE (Buffer.Pointer);
    703     return (AE_OK);
    704 }
    705 
    706 
    707 /*******************************************************************************
    708  *
    709  * FUNCTION:    AcpiDbWalkForSpecificObjects
    710  *
    711  * PARAMETERS:  Callback from WalkNamespace
    712  *
    713  * RETURN:      Status
    714  *
    715  * DESCRIPTION: Display short info about objects in the namespace
    716  *
    717  ******************************************************************************/
    718 
    719 static ACPI_STATUS
    720 AcpiDbWalkForSpecificObjects (
    721     ACPI_HANDLE             ObjHandle,
    722     UINT32                  NestingLevel,
    723     void                    *Context,
    724     void                    **ReturnValue)
    725 {
    726     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
    727     ACPI_BUFFER             Buffer;
    728     ACPI_STATUS             Status;
    729 
    730 
    731     Info->Count++;
    732 
    733     /* Get and display the full pathname to this object */
    734 
    735     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    736     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
    737     if (ACPI_FAILURE (Status))
    738     {
    739         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
    740         return (AE_OK);
    741     }
    742 
    743     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
    744     ACPI_FREE (Buffer.Pointer);
    745 
    746     /* Dump short info about the object */
    747 
    748     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
    749     return (AE_OK);
    750 }
    751 
    752 
    753 /*******************************************************************************
    754  *
    755  * FUNCTION:    AcpiDbDisplayObjects
    756  *
    757  * PARAMETERS:  ObjTypeArg          - Type of object to display
    758  *              DisplayCountArg     - Max depth to display
    759  *
    760  * RETURN:      None
    761  *
    762  * DESCRIPTION: Display objects in the namespace of the requested type
    763  *
    764  ******************************************************************************/
    765 
    766 ACPI_STATUS
    767 AcpiDbDisplayObjects (
    768     char                    *ObjTypeArg,
    769     char                    *DisplayCountArg)
    770 {
    771     ACPI_WALK_INFO          Info;
    772     ACPI_OBJECT_TYPE        Type;
    773     ACPI_OBJECT_INFO        *ObjectInfo;
    774     UINT32                  i;
    775     UINT32                  TotalObjects = 0;
    776 
    777 
    778     /* No argument means display summary/count of all object types */
    779 
    780     if (!ObjTypeArg)
    781     {
    782         ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO));
    783 
    784         if (!ObjectInfo)
    785                 return (AE_NO_MEMORY);
    786 
    787         /* Walk the namespace from the root */
    788 
    789         (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    790             ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL,
    791             (void *) ObjectInfo, NULL);
    792 
    793         AcpiOsPrintf ("\nSummary of namespace objects:\n\n");
    794 
    795         for (i = 0; i < ACPI_TOTAL_TYPES; i++)
    796         {
    797             AcpiOsPrintf ("%8u   %s\n", ObjectInfo->Types[i],
    798                 AcpiUtGetTypeName (i));
    799 
    800             TotalObjects += ObjectInfo->Types[i];
    801         }
    802 
    803         AcpiOsPrintf ("\n%8u   Total namespace objects\n\n",
    804             TotalObjects);
    805 
    806         ACPI_FREE (ObjectInfo);
    807         return (AE_OK);
    808     }
    809 
    810     /* Get the object type */
    811 
    812     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
    813     if (Type == ACPI_TYPE_NOT_FOUND)
    814     {
    815         AcpiOsPrintf ("Invalid or unsupported argument\n");
    816         return (AE_OK);
    817     }
    818 
    819     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
    820     AcpiOsPrintf (
    821         "Objects of type [%s] defined in the current ACPI Namespace:\n",
    822         AcpiUtGetTypeName (Type));
    823 
    824     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
    825 
    826     Info.Count = 0;
    827     Info.OwnerId = ACPI_OWNER_ID_MAX;
    828     Info.DebugLevel = ACPI_UINT32_MAX;
    829     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    830 
    831     /* Walk the namespace from the root */
    832 
    833     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
    834         AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
    835 
    836     AcpiOsPrintf (
    837         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
    838         Info.Count, AcpiUtGetTypeName (Type));
    839 
    840     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
    841     return (AE_OK);
    842 }
    843 
    844 
    845 /*******************************************************************************
    846  *
    847  * FUNCTION:    AcpiDbDisplayFields
    848  *
    849  * PARAMETERS:  ObjTypeArg          - Type of object to display
    850  *              DisplayCountArg     - Max depth to display
    851  *
    852  * RETURN:      None
    853  *
    854  * DESCRIPTION: Display objects in the namespace of the requested type
    855  *
    856  ******************************************************************************/
    857 
    858 ACPI_STATUS
    859 AcpiDbDisplayFields (
    860     UINT32                  AddressSpaceId)
    861 {
    862     ACPI_REGION_WALK_INFO  Info;
    863 
    864 
    865     Info.Count = 0;
    866     Info.OwnerId = ACPI_OWNER_ID_MAX;
    867     Info.DebugLevel = ACPI_UINT32_MAX;
    868     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
    869     Info.AddressSpaceId = AddressSpaceId;
    870 
    871     /* Walk the namespace from the root */
    872 
    873     (void) AcpiWalkNamespace (ACPI_TYPE_LOCAL_REGION_FIELD, ACPI_ROOT_OBJECT,
    874           ACPI_UINT32_MAX, AcpiDbWalkForFields, NULL,
    875           (void *) &Info, NULL);
    876 
    877     return (AE_OK);
    878 }
    879 
    880 
    881 /*******************************************************************************
    882  *
    883  * FUNCTION:    AcpiDbIntegrityWalk
    884  *
    885  * PARAMETERS:  Callback from WalkNamespace
    886  *
    887  * RETURN:      Status
    888  *
    889  * DESCRIPTION: Examine one NS node for valid values.
    890  *
    891  ******************************************************************************/
    892 
    893 static ACPI_STATUS
    894 AcpiDbIntegrityWalk (
    895     ACPI_HANDLE             ObjHandle,
    896     UINT32                  NestingLevel,
    897     void                    *Context,
    898     void                    **ReturnValue)
    899 {
    900     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
    901     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    902     ACPI_OPERAND_OBJECT     *Object;
    903     BOOLEAN                 Alias = TRUE;
    904 
    905 
    906     Info->Nodes++;
    907 
    908     /* Verify the NS node, and dereference aliases */
    909 
    910     while (Alias)
    911     {
    912         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
    913         {
    914             AcpiOsPrintf (
    915                 "Invalid Descriptor Type for Node %p [%s] - "
    916                 "is %2.2X should be %2.2X\n",
    917                 Node, AcpiUtGetDescriptorName (Node),
    918                 ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED);
    919             return (AE_OK);
    920         }
    921 
    922         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
    923             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
    924         {
    925             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
    926         }
    927         else
    928         {
    929             Alias = FALSE;
    930         }
    931     }
    932 
    933     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
    934     {
    935         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
    936             Node, Node->Type);
    937         return (AE_OK);
    938     }
    939 
    940     if (!AcpiUtValidNameseg (Node->Name.Ascii))
    941     {
    942         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
    943         return (AE_OK);
    944     }
    945 
    946     Object = AcpiNsGetAttachedObject (Node);
    947     if (Object)
    948     {
    949         Info->Objects++;
    950         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
    951         {
    952             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
    953                 Object, AcpiUtGetDescriptorName (Object));
    954         }
    955     }
    956 
    957     return (AE_OK);
    958 }
    959 
    960 
    961 /*******************************************************************************
    962  *
    963  * FUNCTION:    AcpiDbCheckIntegrity
    964  *
    965  * PARAMETERS:  None
    966  *
    967  * RETURN:      None
    968  *
    969  * DESCRIPTION: Check entire namespace for data structure integrity
    970  *
    971  ******************************************************************************/
    972 
    973 void
    974 AcpiDbCheckIntegrity (
    975     void)
    976 {
    977     ACPI_INTEGRITY_INFO     Info = {0,0};
    978 
    979     /* Search all nodes in namespace */
    980 
    981     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    982         ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
    983 
    984     AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
    985         Info.Nodes, Info.Objects);
    986 }
    987 
    988 
    989 /*******************************************************************************
    990  *
    991  * FUNCTION:    AcpiDbWalkForReferences
    992  *
    993  * PARAMETERS:  Callback from WalkNamespace
    994  *
    995  * RETURN:      Status
    996  *
    997  * DESCRIPTION: Check if this namespace object refers to the target object
    998  *              that is passed in as the context value.
    999  *
   1000  * Note: Currently doesn't check subobjects within the Node's object
   1001  *
   1002  ******************************************************************************/
   1003 
   1004 static ACPI_STATUS
   1005 AcpiDbWalkForReferences (
   1006     ACPI_HANDLE             ObjHandle,
   1007     UINT32                  NestingLevel,
   1008     void                    *Context,
   1009     void                    **ReturnValue)
   1010 {
   1011     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
   1012     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
   1013 
   1014 
   1015     /* Check for match against the namespace node itself */
   1016 
   1017     if (Node == (void *) ObjDesc)
   1018     {
   1019         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
   1020             AcpiUtGetNodeName (Node));
   1021     }
   1022 
   1023     /* Check for match against the object attached to the node */
   1024 
   1025     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
   1026     {
   1027         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
   1028             Node, AcpiUtGetNodeName (Node));
   1029     }
   1030 
   1031     return (AE_OK);
   1032 }
   1033 
   1034 
   1035 /*******************************************************************************
   1036  *
   1037  * FUNCTION:    AcpiDbFindReferences
   1038  *
   1039  * PARAMETERS:  ObjectArg       - String with hex value of the object
   1040  *
   1041  * RETURN:      None
   1042  *
   1043  * DESCRIPTION: Search namespace for all references to the input object
   1044  *
   1045  ******************************************************************************/
   1046 
   1047 void
   1048 AcpiDbFindReferences (
   1049     char                    *ObjectArg)
   1050 {
   1051     ACPI_OPERAND_OBJECT     *ObjDesc;
   1052     ACPI_SIZE               Address;
   1053 
   1054 
   1055     /* Convert string to object pointer */
   1056 
   1057     Address = strtoul (ObjectArg, NULL, 16);
   1058     ObjDesc = ACPI_TO_POINTER (Address);
   1059 
   1060     /* Search all nodes in namespace */
   1061 
   1062     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
   1063         ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL,
   1064         (void *) ObjDesc, NULL);
   1065 }
   1066 
   1067 
   1068 /*******************************************************************************
   1069  *
   1070  * FUNCTION:    AcpiDbBusWalk
   1071  *
   1072  * PARAMETERS:  Callback from WalkNamespace
   1073  *
   1074  * RETURN:      Status
   1075  *
   1076  * DESCRIPTION: Display info about device objects that have a corresponding
   1077  *              _PRT method.
   1078  *
   1079  ******************************************************************************/
   1080 
   1081 static ACPI_STATUS
   1082 AcpiDbBusWalk (
   1083     ACPI_HANDLE             ObjHandle,
   1084     UINT32                  NestingLevel,
   1085     void                    *Context,
   1086     void                    **ReturnValue)
   1087 {
   1088     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
   1089     ACPI_STATUS             Status;
   1090     ACPI_BUFFER             Buffer;
   1091     ACPI_NAMESPACE_NODE     *TempNode;
   1092     ACPI_DEVICE_INFO        *Info;
   1093     UINT32                  i;
   1094 
   1095 
   1096     if ((Node->Type != ACPI_TYPE_DEVICE) &&
   1097         (Node->Type != ACPI_TYPE_PROCESSOR))
   1098     {
   1099         return (AE_OK);
   1100     }
   1101 
   1102     /* Exit if there is no _PRT under this device */
   1103 
   1104     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
   1105         ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
   1106     if (ACPI_FAILURE (Status))
   1107     {
   1108         return (AE_OK);
   1109     }
   1110 
   1111     /* Get the full path to this device object */
   1112 
   1113     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
   1114     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
   1115     if (ACPI_FAILURE (Status))
   1116     {
   1117         AcpiOsPrintf ("Could Not get pathname for object %p\n",
   1118             ObjHandle);
   1119         return (AE_OK);
   1120     }
   1121 
   1122     Status = AcpiGetObjectInfo (ObjHandle, &Info);
   1123     if (ACPI_FAILURE (Status))
   1124     {
   1125         return (AE_OK);
   1126     }
   1127 
   1128     /* Display the full path */
   1129 
   1130     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
   1131     ACPI_FREE (Buffer.Pointer);
   1132 
   1133     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
   1134     {
   1135         AcpiOsPrintf ("  - Is PCI Root Bridge");
   1136     }
   1137     AcpiOsPrintf ("\n");
   1138 
   1139     /* _PRT info */
   1140 
   1141     AcpiOsPrintf ("_PRT: %p\n", TempNode);
   1142 
   1143     /* Dump _ADR, _HID, _UID, _CID */
   1144 
   1145     if (Info->Valid & ACPI_VALID_ADR)
   1146     {
   1147         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n",
   1148             ACPI_FORMAT_UINT64 (Info->Address));
   1149     }
   1150     else
   1151     {
   1152         AcpiOsPrintf ("_ADR: <Not Present>\n");
   1153     }
   1154 
   1155     if (Info->Valid & ACPI_VALID_HID)
   1156     {
   1157         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
   1158     }
   1159     else
   1160     {
   1161         AcpiOsPrintf ("_HID: <Not Present>\n");
   1162     }
   1163 
   1164     if (Info->Valid & ACPI_VALID_UID)
   1165     {
   1166         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
   1167     }
   1168     else
   1169     {
   1170         AcpiOsPrintf ("_UID: <Not Present>\n");
   1171     }
   1172 
   1173     if (Info->Valid & ACPI_VALID_CID)
   1174     {
   1175         for (i = 0; i < Info->CompatibleIdList.Count; i++)
   1176         {
   1177             AcpiOsPrintf ("_CID: %s\n",
   1178                 Info->CompatibleIdList.Ids[i].String);
   1179         }
   1180     }
   1181     else
   1182     {
   1183         AcpiOsPrintf ("_CID: <Not Present>\n");
   1184     }
   1185 
   1186     ACPI_FREE (Info);
   1187     return (AE_OK);
   1188 }
   1189 
   1190 
   1191 /*******************************************************************************
   1192  *
   1193  * FUNCTION:    AcpiDbGetBusInfo
   1194  *
   1195  * PARAMETERS:  None
   1196  *
   1197  * RETURN:      None
   1198  *
   1199  * DESCRIPTION: Display info about system buses.
   1200  *
   1201  ******************************************************************************/
   1202 
   1203 void
   1204 AcpiDbGetBusInfo (
   1205     void)
   1206 {
   1207     /* Search all nodes in namespace */
   1208 
   1209     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
   1210         ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL);
   1211 }
   1212