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