dbnames.c revision 281075
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 <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acnamesp.h>
47#include <contrib/dev/acpica/include/acdebug.h>
48#include <contrib/dev/acpica/include/acpredef.h>
49
50
51#ifdef ACPI_DEBUGGER
52
53#define _COMPONENT          ACPI_CA_DEBUGGER
54        ACPI_MODULE_NAME    ("dbnames")
55
56
57/* Local prototypes */
58
59static ACPI_STATUS
60AcpiDbWalkAndMatchName (
61    ACPI_HANDLE             ObjHandle,
62    UINT32                  NestingLevel,
63    void                    *Context,
64    void                    **ReturnValue);
65
66static ACPI_STATUS
67AcpiDbWalkForPredefinedNames (
68    ACPI_HANDLE             ObjHandle,
69    UINT32                  NestingLevel,
70    void                    *Context,
71    void                    **ReturnValue);
72
73static ACPI_STATUS
74AcpiDbWalkForSpecificObjects (
75    ACPI_HANDLE             ObjHandle,
76    UINT32                  NestingLevel,
77    void                    *Context,
78    void                    **ReturnValue);
79
80static ACPI_STATUS
81AcpiDbIntegrityWalk (
82    ACPI_HANDLE             ObjHandle,
83    UINT32                  NestingLevel,
84    void                    *Context,
85    void                    **ReturnValue);
86
87static ACPI_STATUS
88AcpiDbWalkForReferences (
89    ACPI_HANDLE             ObjHandle,
90    UINT32                  NestingLevel,
91    void                    *Context,
92    void                    **ReturnValue);
93
94static ACPI_STATUS
95AcpiDbBusWalk (
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 */
105static 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
146void
147AcpiDbSetScope (
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
207ErrorExit:
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
228void
229AcpiDbDumpNamespace (
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
281void
282AcpiDbDumpNamespacePaths (
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
312void
313AcpiDbDumpNamespaceByOwner (
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
356static ACPI_STATUS
357AcpiDbWalkAndMatchName (
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
421ACPI_STATUS
422AcpiDbFindNameInNamespace (
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
468static ACPI_STATUS
469AcpiDbWalkForPredefinedNames (
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
540void
541AcpiDbCheckPredefinedNames (
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
568static ACPI_STATUS
569AcpiDbWalkForSpecificObjects (
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
615ACPI_STATUS
616AcpiDbDisplayObjects (
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
671static ACPI_STATUS
672AcpiDbIntegrityWalk (
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
749void
750AcpiDbCheckIntegrity (
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
780static ACPI_STATUS
781AcpiDbWalkForReferences (
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
823void
824AcpiDbFindReferences (
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
856static ACPI_STATUS
857AcpiDbBusWalk (
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
976void
977AcpiDbGetBusInfo (
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 */
987