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