]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/contrib/dev/acpica/dbcmds.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / contrib / dev / acpica / dbcmds.c
1 /*******************************************************************************
2  *
3  * Module Name: dbcmds - debug commands and output routines
4  *              $Revision: 1.150 $
5  *
6  ******************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117
118 #include <contrib/dev/acpica/acpi.h>
119 #include <contrib/dev/acpica/acdispat.h>
120 #include <contrib/dev/acpica/amlcode.h>
121 #include <contrib/dev/acpica/acnamesp.h>
122 #include <contrib/dev/acpica/acevents.h>
123 #include <contrib/dev/acpica/acdebug.h>
124 #include <contrib/dev/acpica/acresrc.h>
125 #include <contrib/dev/acpica/acdisasm.h>
126
127
128 #include <contrib/dev/acpica/acparser.h>
129
130 #ifdef ACPI_DEBUGGER
131
132 #define _COMPONENT          ACPI_CA_DEBUGGER
133         ACPI_MODULE_NAME    ("dbcmds")
134
135 /* Local prototypes */
136
137 static ACPI_STATUS
138 AcpiDbIntegrityWalk (
139     ACPI_HANDLE             ObjHandle,
140     UINT32                  NestingLevel,
141     void                    *Context,
142     void                    **ReturnValue);
143
144 static ACPI_STATUS
145 AcpiDbWalkAndMatchName (
146     ACPI_HANDLE             ObjHandle,
147     UINT32                  NestingLevel,
148     void                    *Context,
149     void                    **ReturnValue);
150
151 static ACPI_STATUS
152 AcpiDbWalkForReferences (
153     ACPI_HANDLE             ObjHandle,
154     UINT32                  NestingLevel,
155     void                    *Context,
156     void                    **ReturnValue);
157
158 static ACPI_STATUS
159 AcpiDbWalkForSpecificObjects (
160     ACPI_HANDLE             ObjHandle,
161     UINT32                  NestingLevel,
162     void                    *Context,
163     void                    **ReturnValue);
164
165 static ACPI_NAMESPACE_NODE *
166 AcpiDbConvertToNode (
167     char                    *InString);
168
169 static void
170 AcpiDmCompareAmlResources (
171     UINT8                   *Aml1Buffer,
172     ACPI_RSDESC_SIZE        Aml1BufferLength,
173     UINT8                   *Aml2Buffer,
174     ACPI_RSDESC_SIZE        Aml2BufferLength);
175
176 static ACPI_STATUS
177 AcpiDmTestResourceConversion (
178     ACPI_NAMESPACE_NODE     *Node,
179     char                    *Name);
180
181
182 /*
183  * Arguments for the Objects command
184  * These object types map directly to the ACPI_TYPES
185  */
186 static ARGUMENT_INFO        AcpiDbObjectTypes [] =
187 {
188     {"ANY"},
189     {"INTEGERS"},
190     {"STRINGS"},
191     {"BUFFERS"},
192     {"PACKAGES"},
193     {"FIELDS"},
194     {"DEVICES"},
195     {"EVENTS"},
196     {"METHODS"},
197     {"MUTEXES"},
198     {"REGIONS"},
199     {"POWERRESOURCES"},
200     {"PROCESSORS"},
201     {"THERMALZONES"},
202     {"BUFFERFIELDS"},
203     {"DDBHANDLES"},
204     {"DEBUG"},
205     {"REGIONFIELDS"},
206     {"BANKFIELDS"},
207     {"INDEXFIELDS"},
208     {"REFERENCES"},
209     {"ALIAS"},
210     {NULL}           /* Must be null terminated */
211 };
212
213
214 /*******************************************************************************
215  *
216  * FUNCTION:    AcpiDbConvertToNode
217  *
218  * PARAMETERS:  InString        - String to convert
219  *
220  * RETURN:      Pointer to a NS node
221  *
222  * DESCRIPTION: Convert a string to a valid NS pointer.  Handles numeric or
223  *              alpha strings.
224  *
225  ******************************************************************************/
226
227 static ACPI_NAMESPACE_NODE *
228 AcpiDbConvertToNode (
229     char                    *InString)
230 {
231     ACPI_NAMESPACE_NODE     *Node;
232
233
234     if ((*InString >= 0x30) && (*InString <= 0x39))
235     {
236         /* Numeric argument, convert */
237
238         Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
239         if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
240         {
241             AcpiOsPrintf ("Address %p is invalid in this address space\n",
242                 Node);
243             return (NULL);
244         }
245
246         /* Make sure pointer is valid NS node */
247
248         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
249         {
250             AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
251                     Node, AcpiUtGetDescriptorName (Node));
252             return (NULL);
253         }
254     }
255     else
256     {
257         /* Alpha argument */
258         /* The parameter is a name string that must be resolved to a
259          * Named obj
260          */
261         Node = AcpiDbLocalNsLookup (InString);
262         if (!Node)
263         {
264             Node = AcpiGbl_RootNode;
265         }
266     }
267
268     return (Node);
269 }
270
271
272 /*******************************************************************************
273  *
274  * FUNCTION:    AcpiDbSleep
275  *
276  * PARAMETERS:  ObjectArg       - Desired sleep state (0-5)
277  *
278  * RETURN:      Status
279  *
280  * DESCRIPTION: Simulate a sleep/wake sequence
281  *
282  ******************************************************************************/
283
284 ACPI_STATUS
285 AcpiDbSleep (
286     char                    *ObjectArg)
287 {
288     ACPI_STATUS             Status;
289     UINT8                   SleepState;
290
291
292     SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
293
294     AcpiOsPrintf ("**** Prepare to sleep ****\n");
295     Status = AcpiEnterSleepStatePrep (SleepState);
296     if (ACPI_FAILURE (Status))
297     {
298         return (Status);
299     }
300
301     AcpiOsPrintf ("**** Going to sleep ****\n");
302     Status = AcpiEnterSleepState (SleepState);
303     if (ACPI_FAILURE (Status))
304     {
305         return (Status);
306     }
307
308     AcpiOsPrintf ("**** returning from sleep ****\n");
309     Status = AcpiLeaveSleepState (SleepState);
310
311     return (Status);
312 }
313
314
315 /*******************************************************************************
316  *
317  * FUNCTION:    AcpiDbWalkForReferences
318  *
319  * PARAMETERS:  Callback from WalkNamespace
320  *
321  * RETURN:      Status
322  *
323  * DESCRIPTION: Check if this namespace object refers to the target object
324  *              that is passed in as the context value.
325  *
326  * Note: Currently doesn't check subobjects within the Node's object
327  *
328  ******************************************************************************/
329
330 static ACPI_STATUS
331 AcpiDbWalkForReferences (
332     ACPI_HANDLE             ObjHandle,
333     UINT32                  NestingLevel,
334     void                    *Context,
335     void                    **ReturnValue)
336 {
337     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
338     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
339
340
341     /* Check for match against the namespace node itself */
342
343     if (Node == (void *) ObjDesc)
344     {
345         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
346             AcpiUtGetNodeName (Node));
347     }
348
349     /* Check for match against the object attached to the node */
350
351     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
352     {
353         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
354             Node, AcpiUtGetNodeName (Node));
355     }
356
357     return (AE_OK);
358 }
359
360
361 /*******************************************************************************
362  *
363  * FUNCTION:    AcpiDbFindReferences
364  *
365  * PARAMETERS:  ObjectArg       - String with hex value of the object
366  *
367  * RETURN:      None
368  *
369  * DESCRIPTION: Search namespace for all references to the input object
370  *
371  ******************************************************************************/
372
373 void
374 AcpiDbFindReferences (
375     char                    *ObjectArg)
376 {
377     ACPI_OPERAND_OBJECT     *ObjDesc;
378
379
380     /* Convert string to object pointer */
381
382     ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
383
384     /* Search all nodes in namespace */
385
386     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
387                     AcpiDbWalkForReferences, (void *) ObjDesc, NULL);
388 }
389
390
391 /*******************************************************************************
392  *
393  * FUNCTION:    AcpiDbDisplayLocks
394  *
395  * PARAMETERS:  None
396  *
397  * RETURN:      None
398  *
399  * DESCRIPTION: Display information about internal mutexes.
400  *
401  ******************************************************************************/
402
403 void
404 AcpiDbDisplayLocks (
405     void)
406 {
407     UINT32                  i;
408
409
410     for (i = 0; i < ACPI_MAX_MUTEX; i++)
411     {
412         AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
413             AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
414                 ? "Locked" : "Unlocked");
415     }
416 }
417
418
419 /*******************************************************************************
420  *
421  * FUNCTION:    AcpiDbDisplayTableInfo
422  *
423  * PARAMETERS:  TableArg        - String with name of table to be displayed
424  *
425  * RETURN:      None
426  *
427  * DESCRIPTION: Display information about loaded tables.  Current
428  *              implementation displays all loaded tables.
429  *
430  ******************************************************************************/
431
432 void
433 AcpiDbDisplayTableInfo (
434     char                    *TableArg)
435 {
436     ACPI_NATIVE_UINT        i;
437     ACPI_TABLE_DESC         *TableDesc;
438
439
440     /*
441      * Walk the root table list
442      */
443     for (i = 0; i < AcpiGbl_RootTableList.Count; i++)
444     {
445         TableDesc = &AcpiGbl_RootTableList.Tables[i];
446         AcpiOsPrintf ( "%4.4s at %p length %.5X",
447                 TableDesc->Signature.Ascii, TableDesc->Pointer,
448                 (UINT32) TableDesc->Length);
449
450         if (TableDesc->Pointer && (i != ACPI_TABLE_INDEX_FACS))
451         {
452             AcpiOsPrintf (" OemId=\"%6s\" OemTableId=\"%8s\" OemRevision=%8.8X",
453                     TableDesc->Pointer->OemId,
454                     TableDesc->Pointer->OemTableId,
455                     TableDesc->Pointer->OemRevision);
456         }
457         AcpiOsPrintf ("\n");
458     }
459 }
460
461
462 /*******************************************************************************
463  *
464  * FUNCTION:    AcpiDbUnloadAcpiTable
465  *
466  * PARAMETERS:  TableArg        - Name of the table to be unloaded
467  *              InstanceArg     - Which instance of the table to unload (if
468  *                                there are multiple tables of the same type)
469  *
470  * RETURN:      Nonde
471  *
472  * DESCRIPTION: Unload an ACPI table.
473  *              Instance is not implemented
474  *
475  ******************************************************************************/
476
477 void
478 AcpiDbUnloadAcpiTable (
479     char                    *TableArg,
480     char                    *InstanceArg)
481 {
482 /* TBD: Need to reimplement for new data structures */
483
484 #if 0
485     UINT32                  i;
486     ACPI_STATUS             Status;
487
488
489     /* Search all tables for the target type */
490
491     for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
492     {
493         if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
494                 AcpiGbl_TableData[i].SigLength))
495         {
496             /* Found the table, unload it */
497
498             Status = AcpiUnloadTable (i);
499             if (ACPI_SUCCESS (Status))
500             {
501                 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
502             }
503             else
504             {
505                 AcpiOsPrintf ("%s, while unloading [%s]\n",
506                     AcpiFormatException (Status), TableArg);
507             }
508
509             return;
510         }
511     }
512
513     AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
514 #endif
515 }
516
517
518 /*******************************************************************************
519  *
520  * FUNCTION:    AcpiDbSetMethodBreakpoint
521  *
522  * PARAMETERS:  Location            - AML offset of breakpoint
523  *              WalkState           - Current walk info
524  *              Op                  - Current Op (from parse walk)
525  *
526  * RETURN:      None
527  *
528  * DESCRIPTION: Set a breakpoint in a control method at the specified
529  *              AML offset
530  *
531  ******************************************************************************/
532
533 void
534 AcpiDbSetMethodBreakpoint (
535     char                    *Location,
536     ACPI_WALK_STATE         *WalkState,
537     ACPI_PARSE_OBJECT       *Op)
538 {
539     UINT32                  Address;
540
541
542     if (!Op)
543     {
544         AcpiOsPrintf ("There is no method currently executing\n");
545         return;
546     }
547
548     /* Get and verify the breakpoint address */
549
550     Address = ACPI_STRTOUL (Location, NULL, 16);
551     if (Address <= Op->Common.AmlOffset)
552     {
553         AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
554             Address, Op->Common.AmlOffset);
555     }
556
557     /* Save breakpoint in current walk */
558
559     WalkState->UserBreakpoint = Address;
560     AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
561 }
562
563
564 /*******************************************************************************
565  *
566  * FUNCTION:    AcpiDbSetMethodCallBreakpoint
567  *
568  * PARAMETERS:  Op                  - Current Op (from parse walk)
569  *
570  * RETURN:      None
571  *
572  * DESCRIPTION: Set a breakpoint in a control method at the specified
573  *              AML offset
574  *
575  ******************************************************************************/
576
577 void
578 AcpiDbSetMethodCallBreakpoint (
579     ACPI_PARSE_OBJECT       *Op)
580 {
581
582
583     if (!Op)
584     {
585         AcpiOsPrintf ("There is no method currently executing\n");
586         return;
587     }
588
589     AcpiGbl_StepToNextCall = TRUE;
590 }
591
592
593 /*******************************************************************************
594  *
595  * FUNCTION:    AcpiDbDisassembleAml
596  *
597  * PARAMETERS:  Statements          - Number of statements to disassemble
598  *              Op                  - Current Op (from parse walk)
599  *
600  * RETURN:      None
601  *
602  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
603  *              of statements specified.
604  *
605  ******************************************************************************/
606
607 void
608 AcpiDbDisassembleAml (
609     char                    *Statements,
610     ACPI_PARSE_OBJECT       *Op)
611 {
612     UINT32                  NumStatements = 8;
613
614
615     if (!Op)
616     {
617         AcpiOsPrintf ("There is no method currently executing\n");
618         return;
619     }
620
621     if (Statements)
622     {
623         NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
624     }
625
626 #ifdef ACPI_DISASSEMBLER
627     AcpiDmDisassemble (NULL, Op, NumStatements);
628 #endif
629 }
630
631
632 /*******************************************************************************
633  *
634  * FUNCTION:    AcpiDbDisassembleMethod
635  *
636  * PARAMETERS:  Name            - Name of control method
637  *
638  * RETURN:      None
639  *
640  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
641  *              of statements specified.
642  *
643  ******************************************************************************/
644
645 ACPI_STATUS
646 AcpiDbDisassembleMethod (
647     char                    *Name)
648 {
649     ACPI_STATUS             Status;
650     ACPI_PARSE_OBJECT       *Op;
651     ACPI_WALK_STATE         *WalkState;
652     ACPI_OPERAND_OBJECT     *ObjDesc;
653     ACPI_NAMESPACE_NODE     *Method;
654
655
656     Method = AcpiDbConvertToNode (Name);
657     if (!Method)
658     {
659         return (AE_BAD_PARAMETER);
660     }
661
662     ObjDesc = Method->Object;
663
664     Op = AcpiPsCreateScopeOp ();
665     if (!Op)
666     {
667         return (AE_NO_MEMORY);
668     }
669
670     /* Create and initialize a new walk state */
671
672     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
673     if (!WalkState)
674     {
675         return (AE_NO_MEMORY);
676     }
677
678     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
679                     ObjDesc->Method.AmlStart,
680                     ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
681     if (ACPI_FAILURE (Status))
682     {
683         return (Status);
684     }
685
686     /* Parse the AML */
687
688     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
689     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
690     Status = AcpiPsParseAml (WalkState);
691
692 #ifdef ACPI_DISASSEMBLER
693     AcpiDmDisassemble (NULL, Op, 0);
694 #endif
695     AcpiPsDeleteParseTree (Op);
696     return (AE_OK);
697 }
698
699
700 /*******************************************************************************
701  *
702  * FUNCTION:    AcpiDbDumpNamespace
703  *
704  * PARAMETERS:  StartArg        - Node to begin namespace dump
705  *              DepthArg        - Maximum tree depth to be dumped
706  *
707  * RETURN:      None
708  *
709  * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
710  *              with type and other information.
711  *
712  ******************************************************************************/
713
714 void
715 AcpiDbDumpNamespace (
716     char                    *StartArg,
717     char                    *DepthArg)
718 {
719     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
720     UINT32                  MaxDepth = ACPI_UINT32_MAX;
721
722
723     /* No argument given, just start at the root and dump entire namespace */
724
725     if (StartArg)
726     {
727         SubtreeEntry = AcpiDbConvertToNode (StartArg);
728         if (!SubtreeEntry)
729         {
730             return;
731         }
732
733         /* Now we can check for the depth argument */
734
735         if (DepthArg)
736         {
737             MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
738         }
739     }
740
741     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
742     AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
743         ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
744
745     /* Display the subtree */
746
747     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
748     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
749         ACPI_OWNER_ID_MAX, SubtreeEntry);
750     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
751 }
752
753
754 /*******************************************************************************
755  *
756  * FUNCTION:    AcpiDbDumpNamespaceByOwner
757  *
758  * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
759  *              DepthArg        - Maximum tree depth to be dumped
760  *
761  * RETURN:      None
762  *
763  * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
764  *
765  ******************************************************************************/
766
767 void
768 AcpiDbDumpNamespaceByOwner (
769     char                    *OwnerArg,
770     char                    *DepthArg)
771 {
772     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
773     UINT32                  MaxDepth = ACPI_UINT32_MAX;
774     ACPI_OWNER_ID           OwnerId;
775
776
777     OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
778
779     /* Now we can check for the depth argument */
780
781     if (DepthArg)
782     {
783         MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
784     }
785
786     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
787     AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
788
789     /* Display the subtree */
790
791     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
792     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
793         SubtreeEntry);
794     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
795 }
796
797
798 /*******************************************************************************
799  *
800  * FUNCTION:    AcpiDbSendNotify
801  *
802  * PARAMETERS:  Name            - Name of ACPI object to send the notify to
803  *              Value           - Value of the notify to send.
804  *
805  * RETURN:      None
806  *
807  * DESCRIPTION: Send an ACPI notification.  The value specified is sent to the
808  *              named object as an ACPI notify.
809  *
810  ******************************************************************************/
811
812 void
813 AcpiDbSendNotify (
814     char                    *Name,
815     UINT32                  Value)
816 {
817     ACPI_NAMESPACE_NODE     *Node;
818     ACPI_STATUS             Status;
819
820
821     /* Translate name to an Named object */
822
823     Node = AcpiDbConvertToNode (Name);
824     if (!Node)
825     {
826         return;
827     }
828
829     /* Decode Named object type */
830
831     switch (Node->Type)
832     {
833     case ACPI_TYPE_DEVICE:
834     case ACPI_TYPE_THERMAL:
835
836          /* Send the notify */
837
838         Status = AcpiEvQueueNotifyRequest (Node, Value);
839         if (ACPI_FAILURE (Status))
840         {
841             AcpiOsPrintf ("Could not queue notify\n");
842         }
843         break;
844
845     default:
846         AcpiOsPrintf ("Named object is not a device or a thermal object\n");
847         break;
848     }
849 }
850
851
852 /*******************************************************************************
853  *
854  * FUNCTION:    AcpiDbSetMethodData
855  *
856  * PARAMETERS:  TypeArg         - L for local, A for argument
857  *              IndexArg        - which one
858  *              ValueArg        - Value to set.
859  *
860  * RETURN:      None
861  *
862  * DESCRIPTION: Set a local or argument for the running control method.
863  *              NOTE: only object supported is Number.
864  *
865  ******************************************************************************/
866
867 void
868 AcpiDbSetMethodData (
869     char                    *TypeArg,
870     char                    *IndexArg,
871     char                    *ValueArg)
872 {
873     char                    Type;
874     UINT32                  Index;
875     UINT32                  Value;
876     ACPI_WALK_STATE         *WalkState;
877     ACPI_OPERAND_OBJECT     *ObjDesc;
878     ACPI_STATUS             Status;
879     ACPI_NAMESPACE_NODE     *Node;
880
881
882     /* Validate TypeArg */
883
884     AcpiUtStrupr (TypeArg);
885     Type = TypeArg[0];
886     if ((Type != 'L') &&
887         (Type != 'A') &&
888         (Type != 'N'))
889     {
890         AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
891         return;
892     }
893
894     Value = ACPI_STRTOUL (ValueArg, NULL, 16);
895
896     if (Type == 'N')
897     {
898         Node = AcpiDbConvertToNode (IndexArg);
899         if (Node->Type != ACPI_TYPE_INTEGER)
900         {
901             AcpiOsPrintf ("Can only set Integer nodes\n");
902             return;
903         }
904         ObjDesc = Node->Object;
905         ObjDesc->Integer.Value = Value;
906         return;
907     }
908
909     /* Get the index and value */
910
911     Index = ACPI_STRTOUL (IndexArg, NULL, 16);
912
913     WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
914     if (!WalkState)
915     {
916         AcpiOsPrintf ("There is no method currently executing\n");
917         return;
918     }
919
920     /* Create and initialize the new object */
921
922     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
923     if (!ObjDesc)
924     {
925         AcpiOsPrintf ("Could not create an internal object\n");
926         return;
927     }
928
929     ObjDesc->Integer.Value = Value;
930
931     /* Store the new object into the target */
932
933     switch (Type)
934     {
935     case 'A':
936
937         /* Set a method argument */
938
939         if (Index > ACPI_METHOD_MAX_ARG)
940         {
941             AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
942             goto Cleanup;
943         }
944
945         Status = AcpiDsStoreObjectToLocal (AML_ARG_OP, Index, ObjDesc,
946                     WalkState);
947         if (ACPI_FAILURE (Status))
948         {
949             goto Cleanup;
950         }
951
952         ObjDesc = WalkState->Arguments[Index].Object;
953
954         AcpiOsPrintf ("Arg%d: ", Index);
955         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
956         break;
957
958     case 'L':
959
960         /* Set a method local */
961
962         if (Index > ACPI_METHOD_MAX_LOCAL)
963         {
964             AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
965             goto Cleanup;
966         }
967
968         Status = AcpiDsStoreObjectToLocal (AML_LOCAL_OP, Index, ObjDesc,
969                     WalkState);
970         if (ACPI_FAILURE (Status))
971         {
972             goto Cleanup;
973         }
974
975         ObjDesc = WalkState->LocalVariables[Index].Object;
976
977         AcpiOsPrintf ("Local%d: ", Index);
978         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
979         break;
980
981     default:
982         break;
983     }
984
985 Cleanup:
986     AcpiUtRemoveReference (ObjDesc);
987 }
988
989
990 /*******************************************************************************
991  *
992  * FUNCTION:    AcpiDbWalkForSpecificObjects
993  *
994  * PARAMETERS:  Callback from WalkNamespace
995  *
996  * RETURN:      Status
997  *
998  * DESCRIPTION: Display short info about objects in the namespace
999  *
1000  ******************************************************************************/
1001
1002 static ACPI_STATUS
1003 AcpiDbWalkForSpecificObjects (
1004     ACPI_HANDLE             ObjHandle,
1005     UINT32                  NestingLevel,
1006     void                    *Context,
1007     void                    **ReturnValue)
1008 {
1009     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
1010     ACPI_BUFFER             Buffer;
1011     ACPI_STATUS             Status;
1012
1013
1014     Info->Count++;
1015
1016     /* Get and display the full pathname to this object */
1017
1018     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1019     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1020     if (ACPI_FAILURE (Status))
1021     {
1022         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1023         return (AE_OK);
1024     }
1025
1026     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1027     ACPI_FREE (Buffer.Pointer);
1028
1029     /* Dump short info about the object */
1030
1031     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1032     return (AE_OK);
1033 }
1034
1035
1036 /*******************************************************************************
1037  *
1038  * FUNCTION:    AcpiDbDisplayObjects
1039  *
1040  * PARAMETERS:  ObjTypeArg          - Type of object to display
1041  *              DisplayCountArg     - Max depth to display
1042  *
1043  * RETURN:      None
1044  *
1045  * DESCRIPTION: Display objects in the namespace of the requested type
1046  *
1047  ******************************************************************************/
1048
1049 ACPI_STATUS
1050 AcpiDbDisplayObjects (
1051     char                    *ObjTypeArg,
1052     char                    *DisplayCountArg)
1053 {
1054     ACPI_WALK_INFO          Info;
1055     ACPI_OBJECT_TYPE        Type;
1056
1057
1058     /* Get the object type */
1059
1060     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1061     if (Type == ACPI_TYPE_NOT_FOUND)
1062     {
1063         AcpiOsPrintf ("Invalid or unsupported argument\n");
1064         return (AE_OK);
1065     }
1066
1067     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1068     AcpiOsPrintf (
1069         "Objects of type [%s] defined in the current ACPI Namespace:\n",
1070         AcpiUtGetTypeName (Type));
1071
1072     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1073
1074     Info.Count = 0;
1075     Info.OwnerId = ACPI_OWNER_ID_MAX;
1076     Info.DebugLevel = ACPI_UINT32_MAX;
1077     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1078
1079     /* Walk the namespace from the root */
1080
1081     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1082                 AcpiDbWalkForSpecificObjects, (void *) &Info, NULL);
1083
1084     AcpiOsPrintf (
1085         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1086         Info.Count, AcpiUtGetTypeName (Type));
1087
1088     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1089     return (AE_OK);
1090 }
1091
1092
1093 /*******************************************************************************
1094  *
1095  * FUNCTION:    AcpiDbWalkAndMatchName
1096  *
1097  * PARAMETERS:  Callback from WalkNamespace
1098  *
1099  * RETURN:      Status
1100  *
1101  * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
1102  *              are supported -- '?' matches any character.
1103  *
1104  ******************************************************************************/
1105
1106 static ACPI_STATUS
1107 AcpiDbWalkAndMatchName (
1108     ACPI_HANDLE             ObjHandle,
1109     UINT32                  NestingLevel,
1110     void                    *Context,
1111     void                    **ReturnValue)
1112 {
1113     ACPI_STATUS             Status;
1114     char                    *RequestedName = (char *) Context;
1115     UINT32                  i;
1116     ACPI_BUFFER             Buffer;
1117     ACPI_WALK_INFO          Info;
1118
1119
1120     /* Check for a name match */
1121
1122     for (i = 0; i < 4; i++)
1123     {
1124         /* Wildcard support */
1125
1126         if ((RequestedName[i] != '?') &&
1127             (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1128         {
1129             /* No match, just exit */
1130
1131             return (AE_OK);
1132         }
1133     }
1134
1135     /* Get the full pathname to this object */
1136
1137     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1138     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1139     if (ACPI_FAILURE (Status))
1140     {
1141         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1142     }
1143     else
1144     {
1145         Info.OwnerId = ACPI_OWNER_ID_MAX;
1146         Info.DebugLevel = ACPI_UINT32_MAX;
1147         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1148
1149         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1150         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1151         ACPI_FREE (Buffer.Pointer);
1152     }
1153
1154     return (AE_OK);
1155 }
1156
1157
1158 /*******************************************************************************
1159  *
1160  * FUNCTION:    AcpiDbFindNameInNamespace
1161  *
1162  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
1163  *                                wildcards are supported.
1164  *
1165  * RETURN:      None
1166  *
1167  * DESCRIPTION: Search the namespace for a given name (with wildcards)
1168  *
1169  ******************************************************************************/
1170
1171 ACPI_STATUS
1172 AcpiDbFindNameInNamespace (
1173     char                    *NameArg)
1174 {
1175
1176     if (ACPI_STRLEN (NameArg) > 4)
1177     {
1178         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1179         return (AE_OK);
1180     }
1181
1182     /* Walk the namespace from the root */
1183
1184     AcpiUtStrupr (NameArg);
1185     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1186                         AcpiDbWalkAndMatchName, NameArg, NULL);
1187
1188     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1189     return (AE_OK);
1190 }
1191
1192
1193 /*******************************************************************************
1194  *
1195  * FUNCTION:    AcpiDbSetScope
1196  *
1197  * PARAMETERS:  Name                - New scope path
1198  *
1199  * RETURN:      Status
1200  *
1201  * DESCRIPTION: Set the "current scope" as maintained by this utility.
1202  *              The scope is used as a prefix to ACPI paths.
1203  *
1204  ******************************************************************************/
1205
1206 void
1207 AcpiDbSetScope (
1208     char                    *Name)
1209 {
1210     ACPI_STATUS             Status;
1211     ACPI_NAMESPACE_NODE     *Node;
1212
1213
1214     if (!Name || Name[0] == 0)
1215     {
1216         AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1217         return;
1218     }
1219
1220     AcpiDbPrepNamestring (Name);
1221
1222     if (Name[0] == '\\')
1223     {
1224         /* Validate new scope from the root */
1225
1226         Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
1227                     &Node);
1228         if (ACPI_FAILURE (Status))
1229         {
1230             goto ErrorExit;
1231         }
1232
1233         ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1234         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1235     }
1236     else
1237     {
1238         /* Validate new scope relative to old scope */
1239
1240         Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
1241                     &Node);
1242         if (ACPI_FAILURE (Status))
1243         {
1244             goto ErrorExit;
1245         }
1246
1247         ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1248         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1249     }
1250
1251     AcpiGbl_DbScopeNode = Node;
1252     AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1253     return;
1254
1255 ErrorExit:
1256
1257     AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1258         Name, AcpiFormatException (Status));
1259 }
1260
1261
1262 /*******************************************************************************
1263  *
1264  * FUNCTION:    AcpiDmCompareAmlResources
1265  *
1266  * PARAMETERS:  Aml1Buffer          - Contains first resource list
1267  *              Aml1BufferLength    - Length of first resource list
1268  *              Aml2Buffer          - Contains second resource list
1269  *              Aml2BufferLength    - Length of second resource list
1270  *
1271  * RETURN:      None
1272  *
1273  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1274  *              order to isolate a miscompare to an individual resource)
1275  *
1276  ******************************************************************************/
1277
1278 static void
1279 AcpiDmCompareAmlResources (
1280     UINT8                   *Aml1Buffer,
1281     ACPI_RSDESC_SIZE        Aml1BufferLength,
1282     UINT8                   *Aml2Buffer,
1283     ACPI_RSDESC_SIZE        Aml2BufferLength)
1284 {
1285     UINT8                   *Aml1;
1286     UINT8                   *Aml2;
1287     ACPI_RSDESC_SIZE        Aml1Length;
1288     ACPI_RSDESC_SIZE        Aml2Length;
1289     ACPI_RSDESC_SIZE        Offset = 0;
1290     UINT8                   ResourceType;
1291     UINT32                  Count = 0;
1292
1293
1294     /* Compare overall buffer sizes (may be different due to size rounding) */
1295
1296     if (Aml1BufferLength != Aml2BufferLength)
1297     {
1298         AcpiOsPrintf (
1299             "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1300             Aml1BufferLength, Aml2BufferLength);
1301     }
1302
1303     Aml1 = Aml1Buffer;
1304     Aml2 = Aml2Buffer;
1305
1306     /* Walk the descriptor lists, comparing each descriptor */
1307
1308     while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1309     {
1310         /* Get the lengths of each descriptor */
1311
1312         Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1313         Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1314         ResourceType = AcpiUtGetResourceType (Aml1);
1315
1316         /* Check for descriptor length match */
1317
1318         if (Aml1Length != Aml2Length)
1319         {
1320             AcpiOsPrintf (
1321                 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1322                 Count, ResourceType, Offset, Aml1Length, Aml2Length);
1323         }
1324
1325         /* Check for descriptor byte match */
1326
1327         else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1328         {
1329             AcpiOsPrintf (
1330                 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1331                 Count, ResourceType, Offset);
1332         }
1333
1334         /* Exit on EndTag descriptor */
1335
1336         if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1337         {
1338             return;
1339         }
1340
1341         /* Point to next descriptor in each buffer */
1342
1343         Count++;
1344         Offset += Aml1Length;
1345         Aml1 += Aml1Length;
1346         Aml2 += Aml2Length;
1347     }
1348 }
1349
1350
1351 /*******************************************************************************
1352  *
1353  * FUNCTION:    AcpiDmTestResourceConversion
1354  *
1355  * PARAMETERS:  Node            - Parent device node
1356  *              Name            - resource method name (_CRS)
1357  *
1358  * RETURN:      Status
1359  *
1360  * DESCRIPTION: Compare the original AML with a conversion of the AML to
1361  *              internal resource list, then back to AML.
1362  *
1363  ******************************************************************************/
1364
1365 static ACPI_STATUS
1366 AcpiDmTestResourceConversion (
1367     ACPI_NAMESPACE_NODE     *Node,
1368     char                    *Name)
1369 {
1370     ACPI_STATUS             Status;
1371     ACPI_BUFFER             ReturnObj;
1372     ACPI_BUFFER             ResourceObj;
1373     ACPI_BUFFER             NewAml;
1374     ACPI_OBJECT             *OriginalAml;
1375
1376
1377     AcpiOsPrintf ("Resource Conversion Comparison:\n");
1378
1379     NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1380     ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1381     ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1382
1383     /* Get the original _CRS AML resource template */
1384
1385     Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1386     if (ACPI_FAILURE (Status))
1387     {
1388         AcpiOsPrintf ("Could not obtain %s: %s\n",
1389             Name, AcpiFormatException (Status));
1390         return (Status);
1391     }
1392
1393     /* Get the AML resource template, converted to internal resource structs */
1394
1395     Status = AcpiGetCurrentResources (Node, &ResourceObj);
1396     if (ACPI_FAILURE (Status))
1397     {
1398         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1399             AcpiFormatException (Status));
1400         goto Exit1;
1401     }
1402
1403     /* Convert internal resource list to external AML resource template */
1404
1405     Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1406     if (ACPI_FAILURE (Status))
1407     {
1408         AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1409             AcpiFormatException (Status));
1410         goto Exit2;
1411     }
1412
1413     /* Compare original AML to the newly created AML resource list */
1414
1415     OriginalAml = ReturnObj.Pointer;
1416
1417     AcpiDmCompareAmlResources (
1418         OriginalAml->Buffer.Pointer, OriginalAml->Buffer.Length,
1419         NewAml.Pointer, NewAml.Length);
1420
1421     /* Cleanup and exit */
1422
1423     ACPI_FREE (NewAml.Pointer);
1424 Exit2:
1425     ACPI_FREE (ResourceObj.Pointer);
1426 Exit1:
1427     ACPI_FREE (ReturnObj.Pointer);
1428     return (Status);
1429 }
1430
1431
1432 /*******************************************************************************
1433  *
1434  * FUNCTION:    AcpiDbDisplayResources
1435  *
1436  * PARAMETERS:  ObjectArg       - String with hex value of the object
1437  *
1438  * RETURN:      None
1439  *
1440  * DESCRIPTION: Display the resource objects associated with a device.
1441  *
1442  ******************************************************************************/
1443
1444 void
1445 AcpiDbDisplayResources (
1446     char                    *ObjectArg)
1447 {
1448     ACPI_NAMESPACE_NODE     *Node;
1449     ACPI_STATUS             Status;
1450     ACPI_BUFFER             ReturnObj;
1451
1452
1453     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1454     AcpiDbgLevel |= ACPI_LV_RESOURCES;
1455
1456     /* Convert string to object pointer */
1457
1458     Node = AcpiDbConvertToNode (ObjectArg);
1459     if (!Node)
1460     {
1461         return;
1462     }
1463
1464     /* Prepare for a return object of arbitrary size */
1465
1466     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1467     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1468
1469     /* _PRT */
1470
1471     AcpiOsPrintf ("Evaluating _PRT\n");
1472
1473     /* Check if _PRT exists */
1474
1475     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1476     if (ACPI_FAILURE (Status))
1477     {
1478         AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1479             AcpiFormatException (Status));
1480         goto GetCrs;
1481     }
1482
1483     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1484     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1485
1486     Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1487     if (ACPI_FAILURE (Status))
1488     {
1489         AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1490             AcpiFormatException (Status));
1491         goto GetCrs;
1492     }
1493
1494     AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1495
1496
1497     /* _CRS */
1498
1499 GetCrs:
1500     AcpiOsPrintf ("Evaluating _CRS\n");
1501
1502     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1503     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1504
1505     /* Check if _CRS exists */
1506
1507     Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1508     if (ACPI_FAILURE (Status))
1509     {
1510         AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1511             AcpiFormatException (Status));
1512         goto GetPrs;
1513     }
1514
1515     /* Get the _CRS resource list */
1516
1517     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1518     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1519
1520     Status = AcpiGetCurrentResources (Node, &ReturnObj);
1521     if (ACPI_FAILURE (Status))
1522     {
1523         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1524             AcpiFormatException (Status));
1525         goto GetPrs;
1526     }
1527
1528     /* Dump the _CRS resource list */
1529
1530     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1531         ReturnObj.Pointer));
1532
1533     /*
1534      * Perform comparison of original AML to newly created AML. This tests both
1535      * the AML->Resource conversion and the Resource->Aml conversion.
1536      */
1537     Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1538
1539     /* Execute _SRS with the resource list */
1540
1541     Status = AcpiSetCurrentResources (Node, &ReturnObj);
1542     if (ACPI_FAILURE (Status))
1543     {
1544         AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1545             AcpiFormatException (Status));
1546         goto GetPrs;
1547     }
1548
1549
1550     /* _PRS */
1551
1552 GetPrs:
1553     AcpiOsPrintf ("Evaluating _PRS\n");
1554
1555     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1556     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1557
1558     /* Check if _PRS exists */
1559
1560     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1561     if (ACPI_FAILURE (Status))
1562     {
1563         AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1564             AcpiFormatException (Status));
1565         goto Cleanup;
1566     }
1567
1568     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1569     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1570
1571     Status = AcpiGetPossibleResources (Node, &ReturnObj);
1572     if (ACPI_FAILURE (Status))
1573     {
1574         AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1575             AcpiFormatException (Status));
1576         goto Cleanup;
1577     }
1578
1579     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1580
1581 Cleanup:
1582
1583     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1584     return;
1585 }
1586
1587
1588 /*******************************************************************************
1589  *
1590  * FUNCTION:    AcpiDbIntegrityWalk
1591  *
1592  * PARAMETERS:  Callback from WalkNamespace
1593  *
1594  * RETURN:      Status
1595  *
1596  * DESCRIPTION: Examine one NS node for valid values.
1597  *
1598  ******************************************************************************/
1599
1600 static ACPI_STATUS
1601 AcpiDbIntegrityWalk (
1602     ACPI_HANDLE             ObjHandle,
1603     UINT32                  NestingLevel,
1604     void                    *Context,
1605     void                    **ReturnValue)
1606 {
1607     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1608     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1609     ACPI_OPERAND_OBJECT     *Object;
1610
1611
1612     Info->Nodes++;
1613     if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1614     {
1615         AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s]\n",
1616             Node, AcpiUtGetDescriptorName (Node));
1617     }
1618
1619     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1620     {
1621         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1622             Node, Node->Type);
1623     }
1624
1625     if (!AcpiUtValidAcpiName (Node->Name.Integer))
1626     {
1627         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1628     }
1629
1630     Object = AcpiNsGetAttachedObject (Node);
1631     if (Object)
1632     {
1633         Info->Objects++;
1634         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1635         {
1636             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1637                 Object, AcpiUtGetDescriptorName (Object));
1638         }
1639     }
1640
1641     return (AE_OK);
1642 }
1643
1644
1645 /*******************************************************************************
1646  *
1647  * FUNCTION:    AcpiDbCheckIntegrity
1648  *
1649  * PARAMETERS:  None
1650  *
1651  * RETURN:      None
1652  *
1653  * DESCRIPTION: Check entire namespace for data structure integrity
1654  *
1655  ******************************************************************************/
1656
1657 void
1658 AcpiDbCheckIntegrity (
1659     void)
1660 {
1661     ACPI_INTEGRITY_INFO     Info = {0,0};
1662
1663     /* Search all nodes in namespace */
1664
1665     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1666                     AcpiDbIntegrityWalk, (void *) &Info, NULL);
1667
1668     AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1669         Info.Nodes, Info.Objects);
1670 }
1671
1672
1673 /*******************************************************************************
1674  *
1675  * FUNCTION:    AcpiDbGenerateGpe
1676  *
1677  * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1678  *              BlockArg        - GPE block number, ascii string
1679  *                                0 or 1 for FADT GPE blocks
1680  *
1681  * RETURN:      None
1682  *
1683  * DESCRIPTION: Generate a GPE
1684  *
1685  ******************************************************************************/
1686
1687 void
1688 AcpiDbGenerateGpe (
1689     char                    *GpeArg,
1690     char                    *BlockArg)
1691 {
1692     UINT32                  BlockNumber;
1693     UINT32                  GpeNumber;
1694     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1695
1696
1697     GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1698     BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1699
1700
1701     GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1702         GpeNumber);
1703     if (!GpeEventInfo)
1704     {
1705         AcpiOsPrintf ("Invalid GPE\n");
1706         return;
1707     }
1708
1709     (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1710 }
1711
1712
1713 /*******************************************************************************
1714  *
1715  * FUNCTION:    AcpiDbBusWalk
1716  *
1717  * PARAMETERS:  Callback from WalkNamespace
1718  *
1719  * RETURN:      Status
1720  *
1721  * DESCRIPTION: Display info about device objects that have a corresponding
1722  *              _PRT method.
1723  *
1724  ******************************************************************************/
1725
1726 static ACPI_STATUS
1727 AcpiDbBusWalk (
1728     ACPI_HANDLE             ObjHandle,
1729     UINT32                  NestingLevel,
1730     void                    *Context,
1731     void                    **ReturnValue)
1732 {
1733     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1734     ACPI_STATUS             Status;
1735     ACPI_BUFFER             Buffer;
1736     ACPI_INTEGER            ADR;
1737     ACPI_DEVICE_ID          Id;
1738     ACPI_COMPATIBLE_ID_LIST *Cid;
1739     ACPI_NAMESPACE_NODE     *TempNode;
1740
1741
1742     /* Exit if there is no _PRT under this device */
1743
1744     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
1745                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
1746     if (ACPI_FAILURE (Status))
1747     {
1748         return (AE_OK);
1749     }
1750
1751     /* Get the full path to this device object */
1752
1753     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1754     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1755     if (ACPI_FAILURE (Status))
1756     {
1757         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1758         return (AE_OK);
1759     }
1760
1761     /* Display the full path */
1762
1763     AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer);
1764     ACPI_FREE (Buffer.Pointer);
1765
1766     /* _PRT info */
1767
1768     AcpiOsPrintf ("_PRT=%p", TempNode);
1769
1770     /* Get the _ADR value */
1771
1772     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR);
1773     if (ACPI_FAILURE (Status))
1774     {
1775         AcpiOsPrintf (" No _ADR      ");
1776     }
1777     else
1778     {
1779         AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR);
1780     }
1781
1782     /* Get the _HID if present */
1783
1784     Status = AcpiUtExecute_HID (Node, &Id);
1785     if (ACPI_SUCCESS (Status))
1786     {
1787         AcpiOsPrintf (" _HID=%s", Id.Value);
1788     }
1789     else
1790     {
1791         AcpiOsPrintf ("             ");
1792     }
1793
1794     /* Get the _UID if present */
1795
1796     Status = AcpiUtExecute_UID (Node, &Id);
1797     if (ACPI_SUCCESS (Status))
1798     {
1799         AcpiOsPrintf (" _UID=%s", Id.Value);
1800     }
1801
1802     /* Get the _CID if present */
1803
1804     Status = AcpiUtExecute_CID (Node, &Cid);
1805     if (ACPI_SUCCESS (Status))
1806     {
1807         AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value);
1808         ACPI_FREE (Cid);
1809     }
1810
1811     AcpiOsPrintf ("\n");
1812     return (AE_OK);
1813 }
1814
1815
1816 /*******************************************************************************
1817  *
1818  * FUNCTION:    AcpiDbGetBusInfo
1819  *
1820  * PARAMETERS:  None
1821  *
1822  * RETURN:      None
1823  *
1824  * DESCRIPTION: Display info about system busses.
1825  *
1826  ******************************************************************************/
1827
1828 void
1829 AcpiDbGetBusInfo (
1830     void)
1831 {
1832     /* Search all nodes in namespace */
1833
1834     (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1835                     AcpiDbBusWalk, NULL, NULL);
1836 }
1837
1838 #endif /* ACPI_DEBUGGER */