xref: /freebsd/sys/contrib/dev/acpica/components/debugger/dbnames.c (revision cc759c1995237364b02829feb9e5fdd1e6ed2c5b)
1 /*******************************************************************************
2  *
3  * Module Name: dbnames - Debugger commands for the acpi namespace
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 
45 #include <contrib/dev/acpica/include/acpi.h>
46 #include <contrib/dev/acpica/include/accommon.h>
47 #include <contrib/dev/acpica/include/acnamesp.h>
48 #include <contrib/dev/acpica/include/acdebug.h>
49 #include <contrib/dev/acpica/include/acpredef.h>
50 
51 
52 #ifdef ACPI_DEBUGGER
53 
54 #define _COMPONENT          ACPI_CA_DEBUGGER
55         ACPI_MODULE_NAME    ("dbnames")
56 
57 
58 /* Local prototypes */
59 
60 static ACPI_STATUS
61 AcpiDbWalkAndMatchName (
62     ACPI_HANDLE             ObjHandle,
63     UINT32                  NestingLevel,
64     void                    *Context,
65     void                    **ReturnValue);
66 
67 static ACPI_STATUS
68 AcpiDbWalkForPredefinedNames (
69     ACPI_HANDLE             ObjHandle,
70     UINT32                  NestingLevel,
71     void                    *Context,
72     void                    **ReturnValue);
73 
74 static ACPI_STATUS
75 AcpiDbWalkForSpecificObjects (
76     ACPI_HANDLE             ObjHandle,
77     UINT32                  NestingLevel,
78     void                    *Context,
79     void                    **ReturnValue);
80 
81 static ACPI_STATUS
82 AcpiDbIntegrityWalk (
83     ACPI_HANDLE             ObjHandle,
84     UINT32                  NestingLevel,
85     void                    *Context,
86     void                    **ReturnValue);
87 
88 static ACPI_STATUS
89 AcpiDbWalkForReferences (
90     ACPI_HANDLE             ObjHandle,
91     UINT32                  NestingLevel,
92     void                    *Context,
93     void                    **ReturnValue);
94 
95 static ACPI_STATUS
96 AcpiDbBusWalk (
97     ACPI_HANDLE             ObjHandle,
98     UINT32                  NestingLevel,
99     void                    *Context,
100     void                    **ReturnValue);
101 
102 /*
103  * Arguments for the Objects command
104  * These object types map directly to the ACPI_TYPES
105  */
106 static ACPI_DB_ARGUMENT_INFO    AcpiDbObjectTypes [] =
107 {
108     {"ANY"},
109     {"INTEGERS"},
110     {"STRINGS"},
111     {"BUFFERS"},
112     {"PACKAGES"},
113     {"FIELDS"},
114     {"DEVICES"},
115     {"EVENTS"},
116     {"METHODS"},
117     {"MUTEXES"},
118     {"REGIONS"},
119     {"POWERRESOURCES"},
120     {"PROCESSORS"},
121     {"THERMALZONES"},
122     {"BUFFERFIELDS"},
123     {"DDBHANDLES"},
124     {"DEBUG"},
125     {"REGIONFIELDS"},
126     {"BANKFIELDS"},
127     {"INDEXFIELDS"},
128     {"REFERENCES"},
129     {"ALIAS"},
130     {NULL}           /* Must be null terminated */
131 };
132 
133 
134 /*******************************************************************************
135  *
136  * FUNCTION:    AcpiDbSetScope
137  *
138  * PARAMETERS:  Name                - New scope path
139  *
140  * RETURN:      Status
141  *
142  * DESCRIPTION: Set the "current scope" as maintained by this utility.
143  *              The scope is used as a prefix to ACPI paths.
144  *
145  ******************************************************************************/
146 
147 void
148 AcpiDbSetScope (
149     char                    *Name)
150 {
151     ACPI_STATUS             Status;
152     ACPI_NAMESPACE_NODE     *Node;
153 
154 
155     if (!Name || Name[0] == 0)
156     {
157         AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
158         return;
159     }
160 
161     AcpiDbPrepNamestring (Name);
162 
163     if (ACPI_IS_ROOT_PREFIX (Name[0]))
164     {
165         /* Validate new scope from the root */
166 
167         Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
168                     &Node);
169         if (ACPI_FAILURE (Status))
170         {
171             goto ErrorExit;
172         }
173 
174         ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
175         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
176     }
177     else
178     {
179         /* Validate new scope relative to old scope */
180 
181         Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
182                     &Node);
183         if (ACPI_FAILURE (Status))
184         {
185             goto ErrorExit;
186         }
187 
188         ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
189         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
190     }
191 
192     AcpiGbl_DbScopeNode = Node;
193     AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
194     return;
195 
196 ErrorExit:
197 
198     AcpiOsPrintf ("Could not attach scope: %s, %s\n",
199         Name, AcpiFormatException (Status));
200 }
201 
202 
203 /*******************************************************************************
204  *
205  * FUNCTION:    AcpiDbDumpNamespace
206  *
207  * PARAMETERS:  StartArg        - Node to begin namespace dump
208  *              DepthArg        - Maximum tree depth to be dumped
209  *
210  * RETURN:      None
211  *
212  * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
213  *              with type and other information.
214  *
215  ******************************************************************************/
216 
217 void
218 AcpiDbDumpNamespace (
219     char                    *StartArg,
220     char                    *DepthArg)
221 {
222     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
223     UINT32                  MaxDepth = ACPI_UINT32_MAX;
224 
225 
226     /* No argument given, just start at the root and dump entire namespace */
227 
228     if (StartArg)
229     {
230         SubtreeEntry = AcpiDbConvertToNode (StartArg);
231         if (!SubtreeEntry)
232         {
233             return;
234         }
235 
236         /* Now we can check for the depth argument */
237 
238         if (DepthArg)
239         {
240             MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
241         }
242     }
243 
244     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
245     AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
246         ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
247 
248     /* Display the subtree */
249 
250     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
251     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
252         ACPI_OWNER_ID_MAX, SubtreeEntry);
253     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
254 }
255 
256 
257 /*******************************************************************************
258  *
259  * FUNCTION:    AcpiDbDumpNamespaceByOwner
260  *
261  * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
262  *              DepthArg        - Maximum tree depth to be dumped
263  *
264  * RETURN:      None
265  *
266  * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
267  *
268  ******************************************************************************/
269 
270 void
271 AcpiDbDumpNamespaceByOwner (
272     char                    *OwnerArg,
273     char                    *DepthArg)
274 {
275     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
276     UINT32                  MaxDepth = ACPI_UINT32_MAX;
277     ACPI_OWNER_ID           OwnerId;
278 
279 
280     OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
281 
282     /* Now we can check for the depth argument */
283 
284     if (DepthArg)
285     {
286         MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
287     }
288 
289     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
290     AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
291 
292     /* Display the subtree */
293 
294     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
295     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
296         SubtreeEntry);
297     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
298 }
299 
300 
301 /*******************************************************************************
302  *
303  * FUNCTION:    AcpiDbWalkAndMatchName
304  *
305  * PARAMETERS:  Callback from WalkNamespace
306  *
307  * RETURN:      Status
308  *
309  * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
310  *              are supported -- '?' matches any character.
311  *
312  ******************************************************************************/
313 
314 static ACPI_STATUS
315 AcpiDbWalkAndMatchName (
316     ACPI_HANDLE             ObjHandle,
317     UINT32                  NestingLevel,
318     void                    *Context,
319     void                    **ReturnValue)
320 {
321     ACPI_STATUS             Status;
322     char                    *RequestedName = (char *) Context;
323     UINT32                  i;
324     ACPI_BUFFER             Buffer;
325     ACPI_WALK_INFO          Info;
326 
327 
328     /* Check for a name match */
329 
330     for (i = 0; i < 4; i++)
331     {
332         /* Wildcard support */
333 
334         if ((RequestedName[i] != '?') &&
335             (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
336         {
337             /* No match, just exit */
338 
339             return (AE_OK);
340         }
341     }
342 
343     /* Get the full pathname to this object */
344 
345     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
346     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
347     if (ACPI_FAILURE (Status))
348     {
349         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
350     }
351     else
352     {
353         Info.OwnerId = ACPI_OWNER_ID_MAX;
354         Info.DebugLevel = ACPI_UINT32_MAX;
355         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
356 
357         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
358         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
359         ACPI_FREE (Buffer.Pointer);
360     }
361 
362     return (AE_OK);
363 }
364 
365 
366 /*******************************************************************************
367  *
368  * FUNCTION:    AcpiDbFindNameInNamespace
369  *
370  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
371  *                                wildcards are supported.
372  *
373  * RETURN:      None
374  *
375  * DESCRIPTION: Search the namespace for a given name (with wildcards)
376  *
377  ******************************************************************************/
378 
379 ACPI_STATUS
380 AcpiDbFindNameInNamespace (
381     char                    *NameArg)
382 {
383     char                    AcpiName[5] = "____";
384     char                    *AcpiNamePtr = AcpiName;
385 
386 
387     if (ACPI_STRLEN (NameArg) > 4)
388     {
389         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
390         return (AE_OK);
391     }
392 
393     /* Pad out name with underscores as necessary to create a 4-char name */
394 
395     AcpiUtStrupr (NameArg);
396     while (*NameArg)
397     {
398         *AcpiNamePtr = *NameArg;
399         AcpiNamePtr++;
400         NameArg++;
401     }
402 
403     /* Walk the namespace from the root */
404 
405     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
406                         AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
407 
408     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
409     return (AE_OK);
410 }
411 
412 
413 /*******************************************************************************
414  *
415  * FUNCTION:    AcpiDbWalkForPredefinedNames
416  *
417  * PARAMETERS:  Callback from WalkNamespace
418  *
419  * RETURN:      Status
420  *
421  * DESCRIPTION: Detect and display predefined ACPI names (names that start with
422  *              an underscore)
423  *
424  ******************************************************************************/
425 
426 static ACPI_STATUS
427 AcpiDbWalkForPredefinedNames (
428     ACPI_HANDLE             ObjHandle,
429     UINT32                  NestingLevel,
430     void                    *Context,
431     void                    **ReturnValue)
432 {
433     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
434     UINT32                      *Count = (UINT32 *) Context;
435     const ACPI_PREDEFINED_INFO  *Predefined;
436     const ACPI_PREDEFINED_INFO  *Package = NULL;
437     char                        *Pathname;
438     char                        StringBuffer[48];
439 
440 
441     Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
442     if (!Predefined)
443     {
444         return (AE_OK);
445     }
446 
447     Pathname = AcpiNsGetExternalPathname (Node);
448     if (!Pathname)
449     {
450         return (AE_OK);
451     }
452 
453     /* If method returns a package, the info is in the next table entry */
454 
455     if (Predefined->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
456     {
457         Package = Predefined + 1;
458     }
459 
460     AcpiUtGetExpectedReturnTypes (StringBuffer,
461         Predefined->Info.ExpectedBtypes);
462 
463     AcpiOsPrintf ("%-32s Arguments %X, Return Types: %s", Pathname,
464         METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList),
465         StringBuffer);
466 
467     if (Package)
468     {
469         AcpiOsPrintf (" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
470             Package->RetInfo.Type, Package->RetInfo.ObjectType1,
471             Package->RetInfo.Count1);
472     }
473 
474     AcpiOsPrintf("\n");
475 
476     /* Check that the declared argument count matches the ACPI spec */
477 
478     AcpiNsCheckAcpiCompliance (Pathname, Node, Predefined);
479 
480     ACPI_FREE (Pathname);
481     (*Count)++;
482     return (AE_OK);
483 }
484 
485 
486 /*******************************************************************************
487  *
488  * FUNCTION:    AcpiDbCheckPredefinedNames
489  *
490  * PARAMETERS:  None
491  *
492  * RETURN:      None
493  *
494  * DESCRIPTION: Validate all predefined names in the namespace
495  *
496  ******************************************************************************/
497 
498 void
499 AcpiDbCheckPredefinedNames (
500     void)
501 {
502     UINT32                  Count = 0;
503 
504 
505     /* Search all nodes in namespace */
506 
507     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
508                 AcpiDbWalkForPredefinedNames, NULL, (void *) &Count, NULL);
509 
510     AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
511 }
512 
513 
514 /*******************************************************************************
515  *
516  * FUNCTION:    AcpiDbWalkForSpecificObjects
517  *
518  * PARAMETERS:  Callback from WalkNamespace
519  *
520  * RETURN:      Status
521  *
522  * DESCRIPTION: Display short info about objects in the namespace
523  *
524  ******************************************************************************/
525 
526 static ACPI_STATUS
527 AcpiDbWalkForSpecificObjects (
528     ACPI_HANDLE             ObjHandle,
529     UINT32                  NestingLevel,
530     void                    *Context,
531     void                    **ReturnValue)
532 {
533     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
534     ACPI_BUFFER             Buffer;
535     ACPI_STATUS             Status;
536 
537 
538     Info->Count++;
539 
540     /* Get and display the full pathname to this object */
541 
542     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
543     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
544     if (ACPI_FAILURE (Status))
545     {
546         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
547         return (AE_OK);
548     }
549 
550     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
551     ACPI_FREE (Buffer.Pointer);
552 
553     /* Dump short info about the object */
554 
555     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
556     return (AE_OK);
557 }
558 
559 
560 /*******************************************************************************
561  *
562  * FUNCTION:    AcpiDbDisplayObjects
563  *
564  * PARAMETERS:  ObjTypeArg          - Type of object to display
565  *              DisplayCountArg     - Max depth to display
566  *
567  * RETURN:      None
568  *
569  * DESCRIPTION: Display objects in the namespace of the requested type
570  *
571  ******************************************************************************/
572 
573 ACPI_STATUS
574 AcpiDbDisplayObjects (
575     char                    *ObjTypeArg,
576     char                    *DisplayCountArg)
577 {
578     ACPI_WALK_INFO          Info;
579     ACPI_OBJECT_TYPE        Type;
580 
581 
582     /* Get the object type */
583 
584     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
585     if (Type == ACPI_TYPE_NOT_FOUND)
586     {
587         AcpiOsPrintf ("Invalid or unsupported argument\n");
588         return (AE_OK);
589     }
590 
591     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
592     AcpiOsPrintf (
593         "Objects of type [%s] defined in the current ACPI Namespace:\n",
594         AcpiUtGetTypeName (Type));
595 
596     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
597 
598     Info.Count = 0;
599     Info.OwnerId = ACPI_OWNER_ID_MAX;
600     Info.DebugLevel = ACPI_UINT32_MAX;
601     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
602 
603     /* Walk the namespace from the root */
604 
605     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
606                 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
607 
608     AcpiOsPrintf (
609         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
610         Info.Count, AcpiUtGetTypeName (Type));
611 
612     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
613     return (AE_OK);
614 }
615 
616 
617 /*******************************************************************************
618  *
619  * FUNCTION:    AcpiDbIntegrityWalk
620  *
621  * PARAMETERS:  Callback from WalkNamespace
622  *
623  * RETURN:      Status
624  *
625  * DESCRIPTION: Examine one NS node for valid values.
626  *
627  ******************************************************************************/
628 
629 static ACPI_STATUS
630 AcpiDbIntegrityWalk (
631     ACPI_HANDLE             ObjHandle,
632     UINT32                  NestingLevel,
633     void                    *Context,
634     void                    **ReturnValue)
635 {
636     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
637     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
638     ACPI_OPERAND_OBJECT     *Object;
639     BOOLEAN                 Alias = TRUE;
640 
641 
642     Info->Nodes++;
643 
644     /* Verify the NS node, and dereference aliases */
645 
646     while (Alias)
647     {
648         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
649         {
650             AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
651                 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
652                 ACPI_DESC_TYPE_NAMED);
653             return (AE_OK);
654         }
655 
656         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
657             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
658         {
659             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
660         }
661         else
662         {
663             Alias = FALSE;
664         }
665     }
666 
667     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
668     {
669         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
670             Node, Node->Type);
671         return (AE_OK);
672     }
673 
674     if (!AcpiUtValidAcpiName (Node->Name.Ascii))
675     {
676         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
677         return (AE_OK);
678     }
679 
680     Object = AcpiNsGetAttachedObject (Node);
681     if (Object)
682     {
683         Info->Objects++;
684         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
685         {
686             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
687                 Object, AcpiUtGetDescriptorName (Object));
688         }
689     }
690 
691     return (AE_OK);
692 }
693 
694 
695 /*******************************************************************************
696  *
697  * FUNCTION:    AcpiDbCheckIntegrity
698  *
699  * PARAMETERS:  None
700  *
701  * RETURN:      None
702  *
703  * DESCRIPTION: Check entire namespace for data structure integrity
704  *
705  ******************************************************************************/
706 
707 void
708 AcpiDbCheckIntegrity (
709     void)
710 {
711     ACPI_INTEGRITY_INFO     Info = {0,0};
712 
713     /* Search all nodes in namespace */
714 
715     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
716                     AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
717 
718     AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
719         Info.Nodes, Info.Objects);
720 }
721 
722 
723 /*******************************************************************************
724  *
725  * FUNCTION:    AcpiDbWalkForReferences
726  *
727  * PARAMETERS:  Callback from WalkNamespace
728  *
729  * RETURN:      Status
730  *
731  * DESCRIPTION: Check if this namespace object refers to the target object
732  *              that is passed in as the context value.
733  *
734  * Note: Currently doesn't check subobjects within the Node's object
735  *
736  ******************************************************************************/
737 
738 static ACPI_STATUS
739 AcpiDbWalkForReferences (
740     ACPI_HANDLE             ObjHandle,
741     UINT32                  NestingLevel,
742     void                    *Context,
743     void                    **ReturnValue)
744 {
745     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
746     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
747 
748 
749     /* Check for match against the namespace node itself */
750 
751     if (Node == (void *) ObjDesc)
752     {
753         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
754             AcpiUtGetNodeName (Node));
755     }
756 
757     /* Check for match against the object attached to the node */
758 
759     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
760     {
761         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
762             Node, AcpiUtGetNodeName (Node));
763     }
764 
765     return (AE_OK);
766 }
767 
768 
769 /*******************************************************************************
770  *
771  * FUNCTION:    AcpiDbFindReferences
772  *
773  * PARAMETERS:  ObjectArg       - String with hex value of the object
774  *
775  * RETURN:      None
776  *
777  * DESCRIPTION: Search namespace for all references to the input object
778  *
779  ******************************************************************************/
780 
781 void
782 AcpiDbFindReferences (
783     char                    *ObjectArg)
784 {
785     ACPI_OPERAND_OBJECT     *ObjDesc;
786     ACPI_SIZE               Address;
787 
788 
789     /* Convert string to object pointer */
790 
791     Address = ACPI_STRTOUL (ObjectArg, NULL, 16);
792     ObjDesc = ACPI_TO_POINTER (Address);
793 
794     /* Search all nodes in namespace */
795 
796     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
797                     AcpiDbWalkForReferences, NULL, (void *) ObjDesc, NULL);
798 }
799 
800 
801 /*******************************************************************************
802  *
803  * FUNCTION:    AcpiDbBusWalk
804  *
805  * PARAMETERS:  Callback from WalkNamespace
806  *
807  * RETURN:      Status
808  *
809  * DESCRIPTION: Display info about device objects that have a corresponding
810  *              _PRT method.
811  *
812  ******************************************************************************/
813 
814 static ACPI_STATUS
815 AcpiDbBusWalk (
816     ACPI_HANDLE             ObjHandle,
817     UINT32                  NestingLevel,
818     void                    *Context,
819     void                    **ReturnValue)
820 {
821     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
822     ACPI_STATUS             Status;
823     ACPI_BUFFER             Buffer;
824     ACPI_NAMESPACE_NODE     *TempNode;
825     ACPI_DEVICE_INFO        *Info;
826     UINT32                  i;
827 
828 
829     if ((Node->Type != ACPI_TYPE_DEVICE) &&
830         (Node->Type != ACPI_TYPE_PROCESSOR))
831     {
832         return (AE_OK);
833     }
834 
835     /* Exit if there is no _PRT under this device */
836 
837     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
838                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
839     if (ACPI_FAILURE (Status))
840     {
841         return (AE_OK);
842     }
843 
844     /* Get the full path to this device object */
845 
846     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
847     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
848     if (ACPI_FAILURE (Status))
849     {
850         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
851         return (AE_OK);
852     }
853 
854     Status = AcpiGetObjectInfo (ObjHandle, &Info);
855     if (ACPI_FAILURE (Status))
856     {
857         return (AE_OK);
858     }
859 
860     /* Display the full path */
861 
862     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
863     ACPI_FREE (Buffer.Pointer);
864 
865     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
866     {
867         AcpiOsPrintf ("  - Is PCI Root Bridge");
868     }
869     AcpiOsPrintf ("\n");
870 
871     /* _PRT info */
872 
873     AcpiOsPrintf ("_PRT: %p\n", TempNode);
874 
875     /* Dump _ADR, _HID, _UID, _CID */
876 
877     if (Info->Valid & ACPI_VALID_ADR)
878     {
879         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
880     }
881     else
882     {
883         AcpiOsPrintf ("_ADR: <Not Present>\n");
884     }
885 
886     if (Info->Valid & ACPI_VALID_HID)
887     {
888         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
889     }
890     else
891     {
892         AcpiOsPrintf ("_HID: <Not Present>\n");
893     }
894 
895     if (Info->Valid & ACPI_VALID_UID)
896     {
897         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
898     }
899     else
900     {
901         AcpiOsPrintf ("_UID: <Not Present>\n");
902     }
903 
904     if (Info->Valid & ACPI_VALID_CID)
905     {
906         for (i = 0; i < Info->CompatibleIdList.Count; i++)
907         {
908             AcpiOsPrintf ("_CID: %s\n",
909                 Info->CompatibleIdList.Ids[i].String);
910         }
911     }
912     else
913     {
914         AcpiOsPrintf ("_CID: <Not Present>\n");
915     }
916 
917     ACPI_FREE (Info);
918     return (AE_OK);
919 }
920 
921 
922 /*******************************************************************************
923  *
924  * FUNCTION:    AcpiDbGetBusInfo
925  *
926  * PARAMETERS:  None
927  *
928  * RETURN:      None
929  *
930  * DESCRIPTION: Display info about system busses.
931  *
932  ******************************************************************************/
933 
934 void
935 AcpiDbGetBusInfo (
936     void)
937 {
938     /* Search all nodes in namespace */
939 
940     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
941                     AcpiDbBusWalk, NULL, NULL, NULL);
942 }
943 
944 #endif /* ACPI_DEBUGGER */
945