xref: /onnv-gate/usr/src/uts/intel/io/acpica/debugger/dbcmds.c (revision 7851:e828bbb1689c)
1 /*******************************************************************************
2  *
3  * Module Name: dbcmds - debug commands and output routines
4  *              $Revision: 1.157 $
5  *
6  ******************************************************************************/
7 
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2008, 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 "acpi.h"
119 #include "acdispat.h"
120 #include "acnamesp.h"
121 #include "acevents.h"
122 #include "acdebug.h"
123 #include "acresrc.h"
124 #include "acdisasm.h"
125 #include "actables.h"
126 #include "acparser.h"
127 
128 #ifdef ACPI_DEBUGGER
129 
130 #define _COMPONENT          ACPI_CA_DEBUGGER
131         ACPI_MODULE_NAME    ("dbcmds")
132 
133 /* Local prototypes */
134 
135 static ACPI_STATUS
136 AcpiDbIntegrityWalk (
137     ACPI_HANDLE             ObjHandle,
138     UINT32                  NestingLevel,
139     void                    *Context,
140     void                    **ReturnValue);
141 
142 static ACPI_STATUS
143 AcpiDbWalkAndMatchName (
144     ACPI_HANDLE             ObjHandle,
145     UINT32                  NestingLevel,
146     void                    *Context,
147     void                    **ReturnValue);
148 
149 static ACPI_STATUS
150 AcpiDbWalkForReferences (
151     ACPI_HANDLE             ObjHandle,
152     UINT32                  NestingLevel,
153     void                    *Context,
154     void                    **ReturnValue);
155 
156 static ACPI_STATUS
157 AcpiDbWalkForSpecificObjects (
158     ACPI_HANDLE             ObjHandle,
159     UINT32                  NestingLevel,
160     void                    *Context,
161     void                    **ReturnValue);
162 
163 static ACPI_NAMESPACE_NODE *
164 AcpiDbConvertToNode (
165     char                    *InString);
166 
167 static void
168 AcpiDmCompareAmlResources (
169     UINT8                   *Aml1Buffer,
170     ACPI_RSDESC_SIZE        Aml1BufferLength,
171     UINT8                   *Aml2Buffer,
172     ACPI_RSDESC_SIZE        Aml2BufferLength);
173 
174 static ACPI_STATUS
175 AcpiDmTestResourceConversion (
176     ACPI_NAMESPACE_NODE     *Node,
177     char                    *Name);
178 
179 
180 /*
181  * Arguments for the Objects command
182  * These object types map directly to the ACPI_TYPES
183  */
184 static ARGUMENT_INFO        AcpiDbObjectTypes [] =
185 {
186     {"ANY"},
187     {"INTEGERS"},
188     {"STRINGS"},
189     {"BUFFERS"},
190     {"PACKAGES"},
191     {"FIELDS"},
192     {"DEVICES"},
193     {"EVENTS"},
194     {"METHODS"},
195     {"MUTEXES"},
196     {"REGIONS"},
197     {"POWERRESOURCES"},
198     {"PROCESSORS"},
199     {"THERMALZONES"},
200     {"BUFFERFIELDS"},
201     {"DDBHANDLES"},
202     {"DEBUG"},
203     {"REGIONFIELDS"},
204     {"BANKFIELDS"},
205     {"INDEXFIELDS"},
206     {"REFERENCES"},
207     {"ALIAS"},
208     {NULL}           /* Must be null terminated */
209 };
210 
211 
212 /*******************************************************************************
213  *
214  * FUNCTION:    AcpiDbConvertToNode
215  *
216  * PARAMETERS:  InString        - String to convert
217  *
218  * RETURN:      Pointer to a NS node
219  *
220  * DESCRIPTION: Convert a string to a valid NS pointer.  Handles numeric or
221  *              alpha strings.
222  *
223  ******************************************************************************/
224 
225 static ACPI_NAMESPACE_NODE *
226 AcpiDbConvertToNode (
227     char                    *InString)
228 {
229     ACPI_NAMESPACE_NODE     *Node;
230 
231 
232     if ((*InString >= 0x30) && (*InString <= 0x39))
233     {
234         /* Numeric argument, convert */
235 
236         Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
237         if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
238         {
239             AcpiOsPrintf ("Address %p is invalid in this address space\n",
240                 Node);
241             return (NULL);
242         }
243 
244         /* Make sure pointer is valid NS node */
245 
246         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
247         {
248             AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
249                     Node, AcpiUtGetDescriptorName (Node));
250             return (NULL);
251         }
252     }
253     else
254     {
255         /* Alpha argument */
256         /* The parameter is a name string that must be resolved to a
257          * Named obj
258          */
259         Node = AcpiDbLocalNsLookup (InString);
260         if (!Node)
261         {
262             Node = AcpiGbl_RootNode;
263         }
264     }
265 
266     return (Node);
267 }
268 
269 
270 /*******************************************************************************
271  *
272  * FUNCTION:    AcpiDbSleep
273  *
274  * PARAMETERS:  ObjectArg       - Desired sleep state (0-5)
275  *
276  * RETURN:      Status
277  *
278  * DESCRIPTION: Simulate a sleep/wake sequence
279  *
280  ******************************************************************************/
281 
282 ACPI_STATUS
283 AcpiDbSleep (
284     char                    *ObjectArg)
285 {
286     ACPI_STATUS             Status;
287     UINT8                   SleepState;
288 
289 
290     SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
291 
292     AcpiOsPrintf ("**** Prepare to sleep ****\n");
293     Status = AcpiEnterSleepStatePrep (SleepState);
294     if (ACPI_FAILURE (Status))
295     {
296         return (Status);
297     }
298 
299     AcpiOsPrintf ("**** Going to sleep ****\n");
300     Status = AcpiEnterSleepState (SleepState);
301     if (ACPI_FAILURE (Status))
302     {
303         return (Status);
304     }
305 
306     AcpiOsPrintf ("**** returning from sleep ****\n");
307     Status = AcpiLeaveSleepState (SleepState);
308 
309     return (Status);
310 }
311 
312 
313 /*******************************************************************************
314  *
315  * FUNCTION:    AcpiDbWalkForReferences
316  *
317  * PARAMETERS:  Callback from WalkNamespace
318  *
319  * RETURN:      Status
320  *
321  * DESCRIPTION: Check if this namespace object refers to the target object
322  *              that is passed in as the context value.
323  *
324  * Note: Currently doesn't check subobjects within the Node's object
325  *
326  ******************************************************************************/
327 
328 static ACPI_STATUS
329 AcpiDbWalkForReferences (
330     ACPI_HANDLE             ObjHandle,
331     UINT32                  NestingLevel,
332     void                    *Context,
333     void                    **ReturnValue)
334 {
335     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
336     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
337 
338 
339     /* Check for match against the namespace node itself */
340 
341     if (Node == (void *) ObjDesc)
342     {
343         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
344             AcpiUtGetNodeName (Node));
345     }
346 
347     /* Check for match against the object attached to the node */
348 
349     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
350     {
351         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
352             Node, AcpiUtGetNodeName (Node));
353     }
354 
355     return (AE_OK);
356 }
357 
358 
359 /*******************************************************************************
360  *
361  * FUNCTION:    AcpiDbFindReferences
362  *
363  * PARAMETERS:  ObjectArg       - String with hex value of the object
364  *
365  * RETURN:      None
366  *
367  * DESCRIPTION: Search namespace for all references to the input object
368  *
369  ******************************************************************************/
370 
371 void
372 AcpiDbFindReferences (
373     char                    *ObjectArg)
374 {
375     ACPI_OPERAND_OBJECT     *ObjDesc;
376 
377 
378     /* Convert string to object pointer */
379 
380     ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
381 
382     /* Search all nodes in namespace */
383 
384     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
385                     AcpiDbWalkForReferences, (void *) ObjDesc, NULL);
386 }
387 
388 
389 /*******************************************************************************
390  *
391  * FUNCTION:    AcpiDbDisplayLocks
392  *
393  * PARAMETERS:  None
394  *
395  * RETURN:      None
396  *
397  * DESCRIPTION: Display information about internal mutexes.
398  *
399  ******************************************************************************/
400 
401 void
402 AcpiDbDisplayLocks (
403     void)
404 {
405     UINT32                  i;
406 
407 
408     for (i = 0; i < ACPI_MAX_MUTEX; i++)
409     {
410         AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
411             AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
412                 ? "Locked" : "Unlocked");
413     }
414 }
415 
416 
417 /*******************************************************************************
418  *
419  * FUNCTION:    AcpiDbDisplayTableInfo
420  *
421  * PARAMETERS:  TableArg        - String with name of table to be displayed
422  *
423  * RETURN:      None
424  *
425  * DESCRIPTION: Display information about loaded tables.  Current
426  *              implementation displays all loaded tables.
427  *
428  ******************************************************************************/
429 
430 void
431 AcpiDbDisplayTableInfo (
432     char                    *TableArg)
433 {
434     UINT32                  i;
435     ACPI_TABLE_DESC         *TableDesc;
436 
437 
438     /* Walk the entire root table list */
439 
440     for (i = 0; i < AcpiGbl_RootTableList.Count; i++)
441     {
442         TableDesc = &AcpiGbl_RootTableList.Tables[i];
443         AcpiOsPrintf ("%d ", i);
444 
445         /* Make sure that the table is mapped */
446 
447         AcpiTbVerifyTable (TableDesc);
448 
449         /* Dump the table header */
450 
451         if (TableDesc->Pointer)
452         {
453             AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
454         }
455         else
456         {
457             /* If the pointer is null, the table has been unloaded */
458 
459             ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
460                 TableDesc->Signature.Ascii));
461         }
462     }
463 }
464 
465 
466 /*******************************************************************************
467  *
468  * FUNCTION:    AcpiDbUnloadAcpiTable
469  *
470  * PARAMETERS:  TableArg        - Name of the table to be unloaded
471  *              InstanceArg     - Which instance of the table to unload (if
472  *                                there are multiple tables of the same type)
473  *
474  * RETURN:      Nonde
475  *
476  * DESCRIPTION: Unload an ACPI table.
477  *              Instance is not implemented
478  *
479  ******************************************************************************/
480 
481 void
482 AcpiDbUnloadAcpiTable (
483     char                    *TableArg,
484     char                    *InstanceArg)
485 {
486 /* TBD: Need to reimplement for new data structures */
487 
488 #if 0
489     UINT32                  i;
490     ACPI_STATUS             Status;
491 
492 
493     /* Search all tables for the target type */
494 
495     for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
496     {
497         if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
498                 AcpiGbl_TableData[i].SigLength))
499         {
500             /* Found the table, unload it */
501 
502             Status = AcpiUnloadTable (i);
503             if (ACPI_SUCCESS (Status))
504             {
505                 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
506             }
507             else
508             {
509                 AcpiOsPrintf ("%s, while unloading [%s]\n",
510                     AcpiFormatException (Status), TableArg);
511             }
512 
513             return;
514         }
515     }
516 
517     AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
518 #endif
519 }
520 
521 
522 /*******************************************************************************
523  *
524  * FUNCTION:    AcpiDbSetMethodBreakpoint
525  *
526  * PARAMETERS:  Location            - AML offset of breakpoint
527  *              WalkState           - Current walk info
528  *              Op                  - Current Op (from parse walk)
529  *
530  * RETURN:      None
531  *
532  * DESCRIPTION: Set a breakpoint in a control method at the specified
533  *              AML offset
534  *
535  ******************************************************************************/
536 
537 void
538 AcpiDbSetMethodBreakpoint (
539     char                    *Location,
540     ACPI_WALK_STATE         *WalkState,
541     ACPI_PARSE_OBJECT       *Op)
542 {
543     UINT32                  Address;
544 
545 
546     if (!Op)
547     {
548         AcpiOsPrintf ("There is no method currently executing\n");
549         return;
550     }
551 
552     /* Get and verify the breakpoint address */
553 
554     Address = ACPI_STRTOUL (Location, NULL, 16);
555     if (Address <= Op->Common.AmlOffset)
556     {
557         AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
558             Address, Op->Common.AmlOffset);
559     }
560 
561     /* Save breakpoint in current walk */
562 
563     WalkState->UserBreakpoint = Address;
564     AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
565 }
566 
567 
568 /*******************************************************************************
569  *
570  * FUNCTION:    AcpiDbSetMethodCallBreakpoint
571  *
572  * PARAMETERS:  Op                  - Current Op (from parse walk)
573  *
574  * RETURN:      None
575  *
576  * DESCRIPTION: Set a breakpoint in a control method at the specified
577  *              AML offset
578  *
579  ******************************************************************************/
580 
581 void
582 AcpiDbSetMethodCallBreakpoint (
583     ACPI_PARSE_OBJECT       *Op)
584 {
585 
586 
587     if (!Op)
588     {
589         AcpiOsPrintf ("There is no method currently executing\n");
590         return;
591     }
592 
593     AcpiGbl_StepToNextCall = TRUE;
594 }
595 
596 
597 /*******************************************************************************
598  *
599  * FUNCTION:    AcpiDbDisassembleAml
600  *
601  * PARAMETERS:  Statements          - Number of statements to disassemble
602  *              Op                  - Current Op (from parse walk)
603  *
604  * RETURN:      None
605  *
606  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
607  *              of statements specified.
608  *
609  ******************************************************************************/
610 
611 void
612 AcpiDbDisassembleAml (
613     char                    *Statements,
614     ACPI_PARSE_OBJECT       *Op)
615 {
616     UINT32                  NumStatements = 8;
617 
618 
619     if (!Op)
620     {
621         AcpiOsPrintf ("There is no method currently executing\n");
622         return;
623     }
624 
625     if (Statements)
626     {
627         NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
628     }
629 
630     AcpiDmDisassemble (NULL, Op, NumStatements);
631 }
632 
633 
634 /*******************************************************************************
635  *
636  * FUNCTION:    AcpiDbDisassembleMethod
637  *
638  * PARAMETERS:  Name            - Name of control method
639  *
640  * RETURN:      None
641  *
642  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
643  *              of statements specified.
644  *
645  ******************************************************************************/
646 
647 ACPI_STATUS
648 AcpiDbDisassembleMethod (
649     char                    *Name)
650 {
651     ACPI_STATUS             Status;
652     ACPI_PARSE_OBJECT       *Op;
653     ACPI_WALK_STATE         *WalkState;
654     ACPI_OPERAND_OBJECT     *ObjDesc;
655     ACPI_NAMESPACE_NODE     *Method;
656 
657 
658     Method = AcpiDbConvertToNode (Name);
659     if (!Method)
660     {
661         return (AE_BAD_PARAMETER);
662     }
663 
664     ObjDesc = Method->Object;
665 
666     Op = AcpiPsCreateScopeOp ();
667     if (!Op)
668     {
669         return (AE_NO_MEMORY);
670     }
671 
672     /* Create and initialize a new walk state */
673 
674     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
675     if (!WalkState)
676     {
677         return (AE_NO_MEMORY);
678     }
679 
680     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
681                     ObjDesc->Method.AmlStart,
682                     ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
683     if (ACPI_FAILURE (Status))
684     {
685         return (Status);
686     }
687 
688     /* Parse the AML */
689 
690     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
691     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
692     Status = AcpiPsParseAml (WalkState);
693 
694     AcpiDmDisassemble (NULL, Op, 0);
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 (ACPI_REFCLASS_ARG, 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 (ACPI_REFCLASS_LOCAL, 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, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
1419         NewAml.Pointer, (ACPI_RSDESC_SIZE) 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     BOOLEAN                 Alias = TRUE;
1611 
1612 
1613     Info->Nodes++;
1614 
1615     /* Verify the NS node, and dereference aliases */
1616 
1617     while (Alias)
1618     {
1619         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1620         {
1621             AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
1622                 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
1623                 ACPI_DESC_TYPE_NAMED);
1624             return (AE_OK);
1625         }
1626 
1627         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
1628             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
1629         {
1630             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
1631         }
1632         else
1633         {
1634             Alias = FALSE;
1635         }
1636     }
1637 
1638     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1639     {
1640         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1641             Node, Node->Type);
1642         return (AE_OK);
1643     }
1644 
1645     if (!AcpiUtValidAcpiName (Node->Name.Integer))
1646     {
1647         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1648         return (AE_OK);
1649     }
1650 
1651     Object = AcpiNsGetAttachedObject (Node);
1652     if (Object)
1653     {
1654         Info->Objects++;
1655         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1656         {
1657             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1658                 Object, AcpiUtGetDescriptorName (Object));
1659         }
1660     }
1661 
1662     return (AE_OK);
1663 }
1664 
1665 
1666 /*******************************************************************************
1667  *
1668  * FUNCTION:    AcpiDbCheckIntegrity
1669  *
1670  * PARAMETERS:  None
1671  *
1672  * RETURN:      None
1673  *
1674  * DESCRIPTION: Check entire namespace for data structure integrity
1675  *
1676  ******************************************************************************/
1677 
1678 void
1679 AcpiDbCheckIntegrity (
1680     void)
1681 {
1682     ACPI_INTEGRITY_INFO     Info = {0,0};
1683 
1684     /* Search all nodes in namespace */
1685 
1686     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1687                     AcpiDbIntegrityWalk, (void *) &Info, NULL);
1688 
1689     AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1690         Info.Nodes, Info.Objects);
1691 }
1692 
1693 
1694 /*******************************************************************************
1695  *
1696  * FUNCTION:    AcpiDbGenerateGpe
1697  *
1698  * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1699  *              BlockArg        - GPE block number, ascii string
1700  *                                0 or 1 for FADT GPE blocks
1701  *
1702  * RETURN:      None
1703  *
1704  * DESCRIPTION: Generate a GPE
1705  *
1706  ******************************************************************************/
1707 
1708 void
1709 AcpiDbGenerateGpe (
1710     char                    *GpeArg,
1711     char                    *BlockArg)
1712 {
1713     UINT32                  BlockNumber;
1714     UINT32                  GpeNumber;
1715     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1716 
1717 
1718     GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1719     BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1720 
1721 
1722     GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1723         GpeNumber);
1724     if (!GpeEventInfo)
1725     {
1726         AcpiOsPrintf ("Invalid GPE\n");
1727         return;
1728     }
1729 
1730     (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1731 }
1732 
1733 
1734 /*******************************************************************************
1735  *
1736  * FUNCTION:    AcpiDbBusWalk
1737  *
1738  * PARAMETERS:  Callback from WalkNamespace
1739  *
1740  * RETURN:      Status
1741  *
1742  * DESCRIPTION: Display info about device objects that have a corresponding
1743  *              _PRT method.
1744  *
1745  ******************************************************************************/
1746 
1747 static ACPI_STATUS
1748 AcpiDbBusWalk (
1749     ACPI_HANDLE             ObjHandle,
1750     UINT32                  NestingLevel,
1751     void                    *Context,
1752     void                    **ReturnValue)
1753 {
1754     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1755     ACPI_STATUS             Status;
1756     ACPI_BUFFER             Buffer;
1757     ACPI_INTEGER            ADR;
1758     ACPI_DEVICE_ID          Id;
1759     ACPI_COMPATIBLE_ID_LIST *Cid;
1760     ACPI_NAMESPACE_NODE     *TempNode;
1761 
1762 
1763     /* Exit if there is no _PRT under this device */
1764 
1765     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
1766                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
1767     if (ACPI_FAILURE (Status))
1768     {
1769         return (AE_OK);
1770     }
1771 
1772     /* Get the full path to this device object */
1773 
1774     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1775     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1776     if (ACPI_FAILURE (Status))
1777     {
1778         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1779         return (AE_OK);
1780     }
1781 
1782     /* Display the full path */
1783 
1784     AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer);
1785     ACPI_FREE (Buffer.Pointer);
1786 
1787     /* _PRT info */
1788 
1789     AcpiOsPrintf ("_PRT=%p", TempNode);
1790 
1791     /* Get the _ADR value */
1792 
1793     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR);
1794     if (ACPI_FAILURE (Status))
1795     {
1796         AcpiOsPrintf (" No _ADR      ");
1797     }
1798     else
1799     {
1800         AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR);
1801     }
1802 
1803     /* Get the _HID if present */
1804 
1805     Status = AcpiUtExecute_HID (Node, &Id);
1806     if (ACPI_SUCCESS (Status))
1807     {
1808         AcpiOsPrintf (" _HID=%s", Id.Value);
1809     }
1810     else
1811     {
1812         AcpiOsPrintf ("             ");
1813     }
1814 
1815     /* Get the _UID if present */
1816 
1817     Status = AcpiUtExecute_UID (Node, &Id);
1818     if (ACPI_SUCCESS (Status))
1819     {
1820         AcpiOsPrintf (" _UID=%s", Id.Value);
1821     }
1822 
1823     /* Get the _CID if present */
1824 
1825     Status = AcpiUtExecute_CID (Node, &Cid);
1826     if (ACPI_SUCCESS (Status))
1827     {
1828         AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value);
1829         ACPI_FREE (Cid);
1830     }
1831 
1832     AcpiOsPrintf ("\n");
1833     return (AE_OK);
1834 }
1835 
1836 
1837 /*******************************************************************************
1838  *
1839  * FUNCTION:    AcpiDbGetBusInfo
1840  *
1841  * PARAMETERS:  None
1842  *
1843  * RETURN:      None
1844  *
1845  * DESCRIPTION: Display info about system busses.
1846  *
1847  ******************************************************************************/
1848 
1849 void
1850 AcpiDbGetBusInfo (
1851     void)
1852 {
1853     /* Search all nodes in namespace */
1854 
1855     (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1856                     AcpiDbBusWalk, NULL, NULL);
1857 }
1858 
1859 #endif /* ACPI_DEBUGGER */
1860