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