xref: /freebsd-src/sys/contrib/dev/acpica/components/debugger/dbnames.c (revision 9c7c683c56f9d25aa7c25c40d530d7a153b19d18)
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 
439 
440     Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
441     if (!Predefined)
442     {
443         return (AE_OK);
444     }
445 
446     Pathname = AcpiNsGetExternalPathname (Node);
447     if (!Pathname)
448     {
449         return (AE_OK);
450     }
451 
452     /* If method returns a package, the info is in the next table entry */
453 
454     if (Predefined->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
455     {
456         Package = Predefined + 1;
457     }
458 
459     AcpiOsPrintf ("%-32s arg %X ret %2.2X", Pathname,
460         (Predefined->Info.ArgumentList & METHOD_ARG_MASK),
461         Predefined->Info.ExpectedBtypes);
462 
463     if (Package)
464     {
465         AcpiOsPrintf (" PkgType %2.2X ObjType %2.2X Count %2.2X",
466             Package->RetInfo.Type, Package->RetInfo.ObjectType1,
467             Package->RetInfo.Count1);
468     }
469 
470     AcpiOsPrintf("\n");
471 
472     AcpiNsCheckParameterCount (Pathname, Node, ACPI_UINT32_MAX, Predefined);
473     ACPI_FREE (Pathname);
474     (*Count)++;
475 
476     return (AE_OK);
477 }
478 
479 
480 /*******************************************************************************
481  *
482  * FUNCTION:    AcpiDbCheckPredefinedNames
483  *
484  * PARAMETERS:  None
485  *
486  * RETURN:      None
487  *
488  * DESCRIPTION: Validate all predefined names in the namespace
489  *
490  ******************************************************************************/
491 
492 void
493 AcpiDbCheckPredefinedNames (
494     void)
495 {
496     UINT32                  Count = 0;
497 
498 
499     /* Search all nodes in namespace */
500 
501     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
502                 AcpiDbWalkForPredefinedNames, NULL, (void *) &Count, NULL);
503 
504     AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
505 }
506 
507 
508 /*******************************************************************************
509  *
510  * FUNCTION:    AcpiDbWalkForSpecificObjects
511  *
512  * PARAMETERS:  Callback from WalkNamespace
513  *
514  * RETURN:      Status
515  *
516  * DESCRIPTION: Display short info about objects in the namespace
517  *
518  ******************************************************************************/
519 
520 static ACPI_STATUS
521 AcpiDbWalkForSpecificObjects (
522     ACPI_HANDLE             ObjHandle,
523     UINT32                  NestingLevel,
524     void                    *Context,
525     void                    **ReturnValue)
526 {
527     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
528     ACPI_BUFFER             Buffer;
529     ACPI_STATUS             Status;
530 
531 
532     Info->Count++;
533 
534     /* Get and display the full pathname to this object */
535 
536     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
537     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
538     if (ACPI_FAILURE (Status))
539     {
540         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
541         return (AE_OK);
542     }
543 
544     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
545     ACPI_FREE (Buffer.Pointer);
546 
547     /* Dump short info about the object */
548 
549     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
550     return (AE_OK);
551 }
552 
553 
554 /*******************************************************************************
555  *
556  * FUNCTION:    AcpiDbDisplayObjects
557  *
558  * PARAMETERS:  ObjTypeArg          - Type of object to display
559  *              DisplayCountArg     - Max depth to display
560  *
561  * RETURN:      None
562  *
563  * DESCRIPTION: Display objects in the namespace of the requested type
564  *
565  ******************************************************************************/
566 
567 ACPI_STATUS
568 AcpiDbDisplayObjects (
569     char                    *ObjTypeArg,
570     char                    *DisplayCountArg)
571 {
572     ACPI_WALK_INFO          Info;
573     ACPI_OBJECT_TYPE        Type;
574 
575 
576     /* Get the object type */
577 
578     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
579     if (Type == ACPI_TYPE_NOT_FOUND)
580     {
581         AcpiOsPrintf ("Invalid or unsupported argument\n");
582         return (AE_OK);
583     }
584 
585     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
586     AcpiOsPrintf (
587         "Objects of type [%s] defined in the current ACPI Namespace:\n",
588         AcpiUtGetTypeName (Type));
589 
590     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
591 
592     Info.Count = 0;
593     Info.OwnerId = ACPI_OWNER_ID_MAX;
594     Info.DebugLevel = ACPI_UINT32_MAX;
595     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
596 
597     /* Walk the namespace from the root */
598 
599     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
600                 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
601 
602     AcpiOsPrintf (
603         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
604         Info.Count, AcpiUtGetTypeName (Type));
605 
606     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
607     return (AE_OK);
608 }
609 
610 
611 /*******************************************************************************
612  *
613  * FUNCTION:    AcpiDbIntegrityWalk
614  *
615  * PARAMETERS:  Callback from WalkNamespace
616  *
617  * RETURN:      Status
618  *
619  * DESCRIPTION: Examine one NS node for valid values.
620  *
621  ******************************************************************************/
622 
623 static ACPI_STATUS
624 AcpiDbIntegrityWalk (
625     ACPI_HANDLE             ObjHandle,
626     UINT32                  NestingLevel,
627     void                    *Context,
628     void                    **ReturnValue)
629 {
630     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
631     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
632     ACPI_OPERAND_OBJECT     *Object;
633     BOOLEAN                 Alias = TRUE;
634 
635 
636     Info->Nodes++;
637 
638     /* Verify the NS node, and dereference aliases */
639 
640     while (Alias)
641     {
642         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
643         {
644             AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
645                 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
646                 ACPI_DESC_TYPE_NAMED);
647             return (AE_OK);
648         }
649 
650         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
651             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
652         {
653             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
654         }
655         else
656         {
657             Alias = FALSE;
658         }
659     }
660 
661     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
662     {
663         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
664             Node, Node->Type);
665         return (AE_OK);
666     }
667 
668     if (!AcpiUtValidAcpiName (Node->Name.Integer))
669     {
670         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
671         return (AE_OK);
672     }
673 
674     Object = AcpiNsGetAttachedObject (Node);
675     if (Object)
676     {
677         Info->Objects++;
678         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
679         {
680             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
681                 Object, AcpiUtGetDescriptorName (Object));
682         }
683     }
684 
685     return (AE_OK);
686 }
687 
688 
689 /*******************************************************************************
690  *
691  * FUNCTION:    AcpiDbCheckIntegrity
692  *
693  * PARAMETERS:  None
694  *
695  * RETURN:      None
696  *
697  * DESCRIPTION: Check entire namespace for data structure integrity
698  *
699  ******************************************************************************/
700 
701 void
702 AcpiDbCheckIntegrity (
703     void)
704 {
705     ACPI_INTEGRITY_INFO     Info = {0,0};
706 
707     /* Search all nodes in namespace */
708 
709     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
710                     AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
711 
712     AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
713         Info.Nodes, Info.Objects);
714 }
715 
716 
717 /*******************************************************************************
718  *
719  * FUNCTION:    AcpiDbWalkForReferences
720  *
721  * PARAMETERS:  Callback from WalkNamespace
722  *
723  * RETURN:      Status
724  *
725  * DESCRIPTION: Check if this namespace object refers to the target object
726  *              that is passed in as the context value.
727  *
728  * Note: Currently doesn't check subobjects within the Node's object
729  *
730  ******************************************************************************/
731 
732 static ACPI_STATUS
733 AcpiDbWalkForReferences (
734     ACPI_HANDLE             ObjHandle,
735     UINT32                  NestingLevel,
736     void                    *Context,
737     void                    **ReturnValue)
738 {
739     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
740     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
741 
742 
743     /* Check for match against the namespace node itself */
744 
745     if (Node == (void *) ObjDesc)
746     {
747         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
748             AcpiUtGetNodeName (Node));
749     }
750 
751     /* Check for match against the object attached to the node */
752 
753     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
754     {
755         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
756             Node, AcpiUtGetNodeName (Node));
757     }
758 
759     return (AE_OK);
760 }
761 
762 
763 /*******************************************************************************
764  *
765  * FUNCTION:    AcpiDbFindReferences
766  *
767  * PARAMETERS:  ObjectArg       - String with hex value of the object
768  *
769  * RETURN:      None
770  *
771  * DESCRIPTION: Search namespace for all references to the input object
772  *
773  ******************************************************************************/
774 
775 void
776 AcpiDbFindReferences (
777     char                    *ObjectArg)
778 {
779     ACPI_OPERAND_OBJECT     *ObjDesc;
780 
781 
782     /* Convert string to object pointer */
783 
784     ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
785 
786     /* Search all nodes in namespace */
787 
788     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
789                     AcpiDbWalkForReferences, NULL, (void *) ObjDesc, NULL);
790 }
791 
792 
793 /*******************************************************************************
794  *
795  * FUNCTION:    AcpiDbBusWalk
796  *
797  * PARAMETERS:  Callback from WalkNamespace
798  *
799  * RETURN:      Status
800  *
801  * DESCRIPTION: Display info about device objects that have a corresponding
802  *              _PRT method.
803  *
804  ******************************************************************************/
805 
806 static ACPI_STATUS
807 AcpiDbBusWalk (
808     ACPI_HANDLE             ObjHandle,
809     UINT32                  NestingLevel,
810     void                    *Context,
811     void                    **ReturnValue)
812 {
813     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
814     ACPI_STATUS             Status;
815     ACPI_BUFFER             Buffer;
816     ACPI_NAMESPACE_NODE     *TempNode;
817     ACPI_DEVICE_INFO        *Info;
818     UINT32                  i;
819 
820 
821     if ((Node->Type != ACPI_TYPE_DEVICE) &&
822         (Node->Type != ACPI_TYPE_PROCESSOR))
823     {
824         return (AE_OK);
825     }
826 
827     /* Exit if there is no _PRT under this device */
828 
829     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
830                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
831     if (ACPI_FAILURE (Status))
832     {
833         return (AE_OK);
834     }
835 
836     /* Get the full path to this device object */
837 
838     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
839     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
840     if (ACPI_FAILURE (Status))
841     {
842         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
843         return (AE_OK);
844     }
845 
846     Status = AcpiGetObjectInfo (ObjHandle, &Info);
847     if (ACPI_FAILURE (Status))
848     {
849         return (AE_OK);
850     }
851 
852     /* Display the full path */
853 
854     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
855     ACPI_FREE (Buffer.Pointer);
856 
857     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
858     {
859         AcpiOsPrintf ("  - Is PCI Root Bridge");
860     }
861     AcpiOsPrintf ("\n");
862 
863     /* _PRT info */
864 
865     AcpiOsPrintf ("_PRT: %p\n", TempNode);
866 
867     /* Dump _ADR, _HID, _UID, _CID */
868 
869     if (Info->Valid & ACPI_VALID_ADR)
870     {
871         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
872     }
873     else
874     {
875         AcpiOsPrintf ("_ADR: <Not Present>\n");
876     }
877 
878     if (Info->Valid & ACPI_VALID_HID)
879     {
880         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
881     }
882     else
883     {
884         AcpiOsPrintf ("_HID: <Not Present>\n");
885     }
886 
887     if (Info->Valid & ACPI_VALID_UID)
888     {
889         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
890     }
891     else
892     {
893         AcpiOsPrintf ("_UID: <Not Present>\n");
894     }
895 
896     if (Info->Valid & ACPI_VALID_CID)
897     {
898         for (i = 0; i < Info->CompatibleIdList.Count; i++)
899         {
900             AcpiOsPrintf ("_CID: %s\n",
901                 Info->CompatibleIdList.Ids[i].String);
902         }
903     }
904     else
905     {
906         AcpiOsPrintf ("_CID: <Not Present>\n");
907     }
908 
909     ACPI_FREE (Info);
910     return (AE_OK);
911 }
912 
913 
914 /*******************************************************************************
915  *
916  * FUNCTION:    AcpiDbGetBusInfo
917  *
918  * PARAMETERS:  None
919  *
920  * RETURN:      None
921  *
922  * DESCRIPTION: Display info about system busses.
923  *
924  ******************************************************************************/
925 
926 void
927 AcpiDbGetBusInfo (
928     void)
929 {
930     /* Search all nodes in namespace */
931 
932     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
933                     AcpiDbBusWalk, NULL, NULL, NULL);
934 }
935 
936 #endif /* ACPI_DEBUGGER */
937