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