xref: /freebsd/sys/contrib/dev/acpica/components/debugger/dbnames.c (revision 273c26a3c3bea87a241d6879abd4f991db180bf0)
1 /*******************************************************************************
2  *
3  * Module Name: dbnames - Debugger commands for the acpi namespace
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, 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 = AcpiNsGetNormalizedPathname (Node, TRUE);
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,
564         NULL, (void *) &Count, NULL);
565 
566     AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
567 }
568 
569 
570 /*******************************************************************************
571  *
572  * FUNCTION:    AcpiDbWalkForObjectCounts
573  *
574  * PARAMETERS:  Callback from WalkNamespace
575  *
576  * RETURN:      Status
577  *
578  * DESCRIPTION: Display short info about objects in the namespace
579  *
580  ******************************************************************************/
581 
582 static ACPI_STATUS
583 AcpiDbWalkForObjectCounts (
584     ACPI_HANDLE             ObjHandle,
585     UINT32                  NestingLevel,
586     void                    *Context,
587     void                    **ReturnValue)
588 {
589     ACPI_OBJECT_INFO        *Info = (ACPI_OBJECT_INFO *) Context;
590     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
591 
592 
593     if (Node->Type > ACPI_TYPE_NS_NODE_MAX)
594     {
595         AcpiOsPrintf ("[%4.4s]: Unknown object type %X\n",
596             Node->Name.Ascii, Node->Type);
597     }
598     else
599     {
600         Info->Types[Node->Type]++;
601     }
602 
603     return (AE_OK);
604 }
605 
606 
607 /*******************************************************************************
608  *
609  * FUNCTION:    AcpiDbWalkForSpecificObjects
610  *
611  * PARAMETERS:  Callback from WalkNamespace
612  *
613  * RETURN:      Status
614  *
615  * DESCRIPTION: Display short info about objects in the namespace
616  *
617  ******************************************************************************/
618 
619 static ACPI_STATUS
620 AcpiDbWalkForSpecificObjects (
621     ACPI_HANDLE             ObjHandle,
622     UINT32                  NestingLevel,
623     void                    *Context,
624     void                    **ReturnValue)
625 {
626     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
627     ACPI_BUFFER             Buffer;
628     ACPI_STATUS             Status;
629 
630 
631     Info->Count++;
632 
633     /* Get and display the full pathname to this object */
634 
635     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
636     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
637     if (ACPI_FAILURE (Status))
638     {
639         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
640         return (AE_OK);
641     }
642 
643     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
644     ACPI_FREE (Buffer.Pointer);
645 
646     /* Dump short info about the object */
647 
648     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
649     return (AE_OK);
650 }
651 
652 
653 /*******************************************************************************
654  *
655  * FUNCTION:    AcpiDbDisplayObjects
656  *
657  * PARAMETERS:  ObjTypeArg          - Type of object to display
658  *              DisplayCountArg     - Max depth to display
659  *
660  * RETURN:      None
661  *
662  * DESCRIPTION: Display objects in the namespace of the requested type
663  *
664  ******************************************************************************/
665 
666 ACPI_STATUS
667 AcpiDbDisplayObjects (
668     char                    *ObjTypeArg,
669     char                    *DisplayCountArg)
670 {
671     ACPI_WALK_INFO          Info;
672     ACPI_OBJECT_TYPE        Type;
673     ACPI_OBJECT_INFO        *ObjectInfo;
674     UINT32                  i;
675     UINT32                  TotalObjects = 0;
676 
677 
678     /* No argument means display summary/count of all object types */
679 
680     if (!ObjTypeArg)
681     {
682         ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO));
683 
684         /* Walk the namespace from the root */
685 
686         (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
687             ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL,
688             (void *) ObjectInfo, NULL);
689 
690         AcpiOsPrintf ("\nSummary of namespace objects:\n\n");
691 
692         for (i = 0; i < ACPI_TOTAL_TYPES; i++)
693         {
694             AcpiOsPrintf ("%8u   %s\n", ObjectInfo->Types[i],
695                 AcpiUtGetTypeName (i));
696 
697             TotalObjects += ObjectInfo->Types[i];
698         }
699 
700         AcpiOsPrintf ("\n%8u   Total namespace objects\n\n",
701             TotalObjects);
702 
703         ACPI_FREE (ObjectInfo);
704         return (AE_OK);
705     }
706 
707     /* Get the object type */
708 
709     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
710     if (Type == ACPI_TYPE_NOT_FOUND)
711     {
712         AcpiOsPrintf ("Invalid or unsupported argument\n");
713         return (AE_OK);
714     }
715 
716     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
717     AcpiOsPrintf (
718         "Objects of type [%s] defined in the current ACPI Namespace:\n",
719         AcpiUtGetTypeName (Type));
720 
721     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
722 
723     Info.Count = 0;
724     Info.OwnerId = ACPI_OWNER_ID_MAX;
725     Info.DebugLevel = ACPI_UINT32_MAX;
726     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
727 
728     /* Walk the namespace from the root */
729 
730     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
731         AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
732 
733     AcpiOsPrintf (
734         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
735         Info.Count, AcpiUtGetTypeName (Type));
736 
737     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
738     return (AE_OK);
739 }
740 
741 
742 /*******************************************************************************
743  *
744  * FUNCTION:    AcpiDbIntegrityWalk
745  *
746  * PARAMETERS:  Callback from WalkNamespace
747  *
748  * RETURN:      Status
749  *
750  * DESCRIPTION: Examine one NS node for valid values.
751  *
752  ******************************************************************************/
753 
754 static ACPI_STATUS
755 AcpiDbIntegrityWalk (
756     ACPI_HANDLE             ObjHandle,
757     UINT32                  NestingLevel,
758     void                    *Context,
759     void                    **ReturnValue)
760 {
761     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
762     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
763     ACPI_OPERAND_OBJECT     *Object;
764     BOOLEAN                 Alias = TRUE;
765 
766 
767     Info->Nodes++;
768 
769     /* Verify the NS node, and dereference aliases */
770 
771     while (Alias)
772     {
773         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
774         {
775             AcpiOsPrintf (
776                 "Invalid Descriptor Type for Node %p [%s] - "
777                 "is %2.2X should be %2.2X\n",
778                 Node, AcpiUtGetDescriptorName (Node),
779                 ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED);
780             return (AE_OK);
781         }
782 
783         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
784             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
785         {
786             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
787         }
788         else
789         {
790             Alias = FALSE;
791         }
792     }
793 
794     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
795     {
796         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
797             Node, Node->Type);
798         return (AE_OK);
799     }
800 
801     if (!AcpiUtValidNameseg (Node->Name.Ascii))
802     {
803         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
804         return (AE_OK);
805     }
806 
807     Object = AcpiNsGetAttachedObject (Node);
808     if (Object)
809     {
810         Info->Objects++;
811         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
812         {
813             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
814                 Object, AcpiUtGetDescriptorName (Object));
815         }
816     }
817 
818     return (AE_OK);
819 }
820 
821 
822 /*******************************************************************************
823  *
824  * FUNCTION:    AcpiDbCheckIntegrity
825  *
826  * PARAMETERS:  None
827  *
828  * RETURN:      None
829  *
830  * DESCRIPTION: Check entire namespace for data structure integrity
831  *
832  ******************************************************************************/
833 
834 void
835 AcpiDbCheckIntegrity (
836     void)
837 {
838     ACPI_INTEGRITY_INFO     Info = {0,0};
839 
840     /* Search all nodes in namespace */
841 
842     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
843         ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
844 
845     AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
846         Info.Nodes, Info.Objects);
847 }
848 
849 
850 /*******************************************************************************
851  *
852  * FUNCTION:    AcpiDbWalkForReferences
853  *
854  * PARAMETERS:  Callback from WalkNamespace
855  *
856  * RETURN:      Status
857  *
858  * DESCRIPTION: Check if this namespace object refers to the target object
859  *              that is passed in as the context value.
860  *
861  * Note: Currently doesn't check subobjects within the Node's object
862  *
863  ******************************************************************************/
864 
865 static ACPI_STATUS
866 AcpiDbWalkForReferences (
867     ACPI_HANDLE             ObjHandle,
868     UINT32                  NestingLevel,
869     void                    *Context,
870     void                    **ReturnValue)
871 {
872     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
873     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
874 
875 
876     /* Check for match against the namespace node itself */
877 
878     if (Node == (void *) ObjDesc)
879     {
880         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
881             AcpiUtGetNodeName (Node));
882     }
883 
884     /* Check for match against the object attached to the node */
885 
886     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
887     {
888         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
889             Node, AcpiUtGetNodeName (Node));
890     }
891 
892     return (AE_OK);
893 }
894 
895 
896 /*******************************************************************************
897  *
898  * FUNCTION:    AcpiDbFindReferences
899  *
900  * PARAMETERS:  ObjectArg       - String with hex value of the object
901  *
902  * RETURN:      None
903  *
904  * DESCRIPTION: Search namespace for all references to the input object
905  *
906  ******************************************************************************/
907 
908 void
909 AcpiDbFindReferences (
910     char                    *ObjectArg)
911 {
912     ACPI_OPERAND_OBJECT     *ObjDesc;
913     ACPI_SIZE               Address;
914 
915 
916     /* Convert string to object pointer */
917 
918     Address = strtoul (ObjectArg, NULL, 16);
919     ObjDesc = ACPI_TO_POINTER (Address);
920 
921     /* Search all nodes in namespace */
922 
923     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
924         ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL,
925         (void *) ObjDesc, NULL);
926 }
927 
928 
929 /*******************************************************************************
930  *
931  * FUNCTION:    AcpiDbBusWalk
932  *
933  * PARAMETERS:  Callback from WalkNamespace
934  *
935  * RETURN:      Status
936  *
937  * DESCRIPTION: Display info about device objects that have a corresponding
938  *              _PRT method.
939  *
940  ******************************************************************************/
941 
942 static ACPI_STATUS
943 AcpiDbBusWalk (
944     ACPI_HANDLE             ObjHandle,
945     UINT32                  NestingLevel,
946     void                    *Context,
947     void                    **ReturnValue)
948 {
949     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
950     ACPI_STATUS             Status;
951     ACPI_BUFFER             Buffer;
952     ACPI_NAMESPACE_NODE     *TempNode;
953     ACPI_DEVICE_INFO        *Info;
954     UINT32                  i;
955 
956 
957     if ((Node->Type != ACPI_TYPE_DEVICE) &&
958         (Node->Type != ACPI_TYPE_PROCESSOR))
959     {
960         return (AE_OK);
961     }
962 
963     /* Exit if there is no _PRT under this device */
964 
965     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
966         ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
967     if (ACPI_FAILURE (Status))
968     {
969         return (AE_OK);
970     }
971 
972     /* Get the full path to this device object */
973 
974     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
975     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE);
976     if (ACPI_FAILURE (Status))
977     {
978         AcpiOsPrintf ("Could Not get pathname for object %p\n",
979             ObjHandle);
980         return (AE_OK);
981     }
982 
983     Status = AcpiGetObjectInfo (ObjHandle, &Info);
984     if (ACPI_FAILURE (Status))
985     {
986         return (AE_OK);
987     }
988 
989     /* Display the full path */
990 
991     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
992     ACPI_FREE (Buffer.Pointer);
993 
994     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
995     {
996         AcpiOsPrintf ("  - Is PCI Root Bridge");
997     }
998     AcpiOsPrintf ("\n");
999 
1000     /* _PRT info */
1001 
1002     AcpiOsPrintf ("_PRT: %p\n", TempNode);
1003 
1004     /* Dump _ADR, _HID, _UID, _CID */
1005 
1006     if (Info->Valid & ACPI_VALID_ADR)
1007     {
1008         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n",
1009             ACPI_FORMAT_UINT64 (Info->Address));
1010     }
1011     else
1012     {
1013         AcpiOsPrintf ("_ADR: <Not Present>\n");
1014     }
1015 
1016     if (Info->Valid & ACPI_VALID_HID)
1017     {
1018         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
1019     }
1020     else
1021     {
1022         AcpiOsPrintf ("_HID: <Not Present>\n");
1023     }
1024 
1025     if (Info->Valid & ACPI_VALID_UID)
1026     {
1027         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
1028     }
1029     else
1030     {
1031         AcpiOsPrintf ("_UID: <Not Present>\n");
1032     }
1033 
1034     if (Info->Valid & ACPI_VALID_CID)
1035     {
1036         for (i = 0; i < Info->CompatibleIdList.Count; i++)
1037         {
1038             AcpiOsPrintf ("_CID: %s\n",
1039                 Info->CompatibleIdList.Ids[i].String);
1040         }
1041     }
1042     else
1043     {
1044         AcpiOsPrintf ("_CID: <Not Present>\n");
1045     }
1046 
1047     ACPI_FREE (Info);
1048     return (AE_OK);
1049 }
1050 
1051 
1052 /*******************************************************************************
1053  *
1054  * FUNCTION:    AcpiDbGetBusInfo
1055  *
1056  * PARAMETERS:  None
1057  *
1058  * RETURN:      None
1059  *
1060  * DESCRIPTION: Display info about system busses.
1061  *
1062  ******************************************************************************/
1063 
1064 void
1065 AcpiDbGetBusInfo (
1066     void)
1067 {
1068     /* Search all nodes in namespace */
1069 
1070     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1071         ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL);
1072 }
1073