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