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