xref: /onnv-gate/usr/src/uts/intel/io/acpica/debugger/dbcmds.c (revision 9980:13d7f3eec672)
1 /*******************************************************************************
2  *
3  * Module Name: dbcmds - debug commands and output routines
4  *
5  ******************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 
117 #include "acpi.h"
118 #include "accommon.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:    AcpiDbWalkForPredefinedNames
392  *
393  * PARAMETERS:  Callback from WalkNamespace
394  *
395  * RETURN:      Status
396  *
397  * DESCRIPTION: Detect and display predefined ACPI names (names that start with
398  *              an underscore)
399  *
400  ******************************************************************************/
401 
402 static ACPI_STATUS
403 AcpiDbWalkForPredefinedNames (
404     ACPI_HANDLE             ObjHandle,
405     UINT32                  NestingLevel,
406     void                    *Context,
407     void                    **ReturnValue)
408 {
409     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
410     UINT32                      *Count = (UINT32 *) Context;
411     const ACPI_PREDEFINED_INFO  *Predefined;
412     const ACPI_PREDEFINED_INFO  *Package = NULL;
413     char                        *Pathname;
414 
415 
416     Predefined = AcpiNsCheckForPredefinedName (Node);
417     if (!Predefined)
418     {
419         return (AE_OK);
420     }
421 
422     Pathname = AcpiNsGetExternalPathname (Node);
423     if (!Pathname)
424     {
425         return (AE_OK);
426     }
427 
428     /* If method returns a package, the info is in the next table entry */
429 
430     if (Predefined->Info.ExpectedBtypes & ACPI_BTYPE_PACKAGE)
431     {
432         Package = Predefined + 1;
433     }
434 
435     AcpiOsPrintf ("%-32s arg %X ret %2.2X", Pathname,
436         Predefined->Info.ParamCount, Predefined->Info.ExpectedBtypes);
437 
438     if (Package)
439     {
440         AcpiOsPrintf (" PkgType %2.2X ObjType %2.2X Count %2.2X",
441             Package->RetInfo.Type, Package->RetInfo.ObjectType1,
442             Package->RetInfo.Count1);
443     }
444 
445     AcpiOsPrintf("\n");
446 
447     AcpiNsCheckParameterCount (Pathname, Node, ACPI_UINT32_MAX, Predefined);
448     ACPI_FREE (Pathname);
449     (*Count)++;
450 
451     return (AE_OK);
452 }
453 
454 
455 /*******************************************************************************
456  *
457  * FUNCTION:    AcpiDbCheckPredefinedNames
458  *
459  * PARAMETERS:  None
460  *
461  * RETURN:      None
462  *
463  * DESCRIPTION: Validate all predefined names in the namespace
464  *
465  ******************************************************************************/
466 
467 void
468 AcpiDbCheckPredefinedNames (
469     void)
470 {
471     UINT32                  Count = 0;
472 
473 
474     /* Search all nodes in namespace */
475 
476     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
477                 AcpiDbWalkForPredefinedNames, (void *) &Count, NULL);
478 
479     AcpiOsPrintf ("Found %d predefined names in the namespace\n", Count);
480 }
481 
482 
483 /*******************************************************************************
484  *
485  * FUNCTION:    AcpiDbWalkForExecute
486  *
487  * PARAMETERS:  Callback from WalkNamespace
488  *
489  * RETURN:      Status
490  *
491  * DESCRIPTION: Batch execution module. Currently only executes predefined
492  *              ACPI names.
493  *
494  ******************************************************************************/
495 
496 static ACPI_STATUS
497 AcpiDbWalkForExecute (
498     ACPI_HANDLE             ObjHandle,
499     UINT32                  NestingLevel,
500     void                    *Context,
501     void                    **ReturnValue)
502 {
503     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
504     UINT32                      *Count = (UINT32 *) Context;
505     const ACPI_PREDEFINED_INFO  *Predefined;
506     ACPI_BUFFER                 ReturnObj;
507     ACPI_STATUS                 Status;
508     char                        *Pathname;
509     ACPI_BUFFER             Buffer;
510     UINT32                  i;
511     ACPI_DEVICE_INFO        *ObjInfo;
512     ACPI_OBJECT_LIST        ParamObjects;
513     ACPI_OBJECT             Params[ACPI_METHOD_NUM_ARGS];
514 
515 
516     Predefined = AcpiNsCheckForPredefinedName (Node);
517     if (!Predefined)
518     {
519         return (AE_OK);
520     }
521 
522     if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
523     {
524         return (AE_OK);
525     }
526 
527     Pathname = AcpiNsGetExternalPathname (Node);
528     if (!Pathname)
529     {
530         return (AE_OK);
531     }
532 
533     /* Get the object info for number of method parameters */
534 
535     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
536     Status = AcpiGetObjectInfo (ObjHandle, &Buffer);
537     if (ACPI_FAILURE (Status))
538     {
539         return (Status);
540     }
541 
542     ParamObjects.Pointer = NULL;
543     ParamObjects.Count   = 0;
544 
545     ObjInfo = Buffer.Pointer;
546     if (ObjInfo->Type == ACPI_TYPE_METHOD)
547     {
548 
549         /* Setup default parameters */
550 
551         for (i = 0; i < ObjInfo->ParamCount; i++)
552         {
553             Params[i].Type           = ACPI_TYPE_INTEGER;
554             Params[i].Integer.Value  = 1;
555         }
556 
557         ParamObjects.Pointer     = Params;
558         ParamObjects.Count       = ObjInfo->ParamCount;
559     }
560 
561     ACPI_FREE (Buffer.Pointer);
562 
563     ReturnObj.Pointer = NULL;
564     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
565 
566 
567     /* Do the actual method execution */
568 
569     AcpiGbl_MethodExecuting = TRUE;
570 
571     Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
572 
573     AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status));
574     AcpiGbl_MethodExecuting = FALSE;
575 
576     ACPI_FREE (Pathname);
577     (*Count)++;
578 
579     return (AE_OK);
580 }
581 
582 
583 /*******************************************************************************
584  *
585  * FUNCTION:    AcpiDbBatchExecute
586  *
587  * PARAMETERS:  None
588  *
589  * RETURN:      None
590  *
591  * DESCRIPTION: Namespace batch execution.
592  *
593  ******************************************************************************/
594 
595 void
596 AcpiDbBatchExecute (
597     void)
598 {
599     UINT32                  Count = 0;
600 
601 
602     /* Search all nodes in namespace */
603 
604     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
605                 AcpiDbWalkForExecute, (void *) &Count, NULL);
606 
607     AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Count);
608 }
609 
610 
611 /*******************************************************************************
612  *
613  * FUNCTION:    AcpiDbDisplayLocks
614  *
615  * PARAMETERS:  None
616  *
617  * RETURN:      None
618  *
619  * DESCRIPTION: Display information about internal mutexes.
620  *
621  ******************************************************************************/
622 
623 void
624 AcpiDbDisplayLocks (
625     void)
626 {
627     UINT32                  i;
628 
629 
630     for (i = 0; i < ACPI_MAX_MUTEX; i++)
631     {
632         AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
633             AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
634                 ? "Locked" : "Unlocked");
635     }
636 }
637 
638 
639 /*******************************************************************************
640  *
641  * FUNCTION:    AcpiDbDisplayTableInfo
642  *
643  * PARAMETERS:  TableArg        - String with name of table to be displayed
644  *
645  * RETURN:      None
646  *
647  * DESCRIPTION: Display information about loaded tables.  Current
648  *              implementation displays all loaded tables.
649  *
650  ******************************************************************************/
651 
652 void
653 AcpiDbDisplayTableInfo (
654     char                    *TableArg)
655 {
656     UINT32                  i;
657     ACPI_TABLE_DESC         *TableDesc;
658     ACPI_STATUS             Status;
659 
660 
661     /* Walk the entire root table list */
662 
663     for (i = 0; i < AcpiGbl_RootTableList.Count; i++)
664     {
665         TableDesc = &AcpiGbl_RootTableList.Tables[i];
666         AcpiOsPrintf ("%d ", i);
667 
668         /* Make sure that the table is mapped */
669 
670         Status = AcpiTbVerifyTable (TableDesc);
671         if (ACPI_FAILURE (Status))
672         {
673             return;
674         }
675 
676         /* Dump the table header */
677 
678         if (TableDesc->Pointer)
679         {
680             AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
681         }
682         else
683         {
684             /* If the pointer is null, the table has been unloaded */
685 
686             ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
687                 TableDesc->Signature.Ascii));
688         }
689     }
690 }
691 
692 
693 /*******************************************************************************
694  *
695  * FUNCTION:    AcpiDbUnloadAcpiTable
696  *
697  * PARAMETERS:  TableArg        - Name of the table to be unloaded
698  *              InstanceArg     - Which instance of the table to unload (if
699  *                                there are multiple tables of the same type)
700  *
701  * RETURN:      Nonde
702  *
703  * DESCRIPTION: Unload an ACPI table.
704  *              Instance is not implemented
705  *
706  ******************************************************************************/
707 
708 void
709 AcpiDbUnloadAcpiTable (
710     char                    *TableArg,
711     char                    *InstanceArg)
712 {
713 /* TBD: Need to reimplement for new data structures */
714 
715 #if 0
716     UINT32                  i;
717     ACPI_STATUS             Status;
718 
719 
720     /* Search all tables for the target type */
721 
722     for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
723     {
724         if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
725                 AcpiGbl_TableData[i].SigLength))
726         {
727             /* Found the table, unload it */
728 
729             Status = AcpiUnloadTable (i);
730             if (ACPI_SUCCESS (Status))
731             {
732                 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
733             }
734             else
735             {
736                 AcpiOsPrintf ("%s, while unloading [%s]\n",
737                     AcpiFormatException (Status), TableArg);
738             }
739 
740             return;
741         }
742     }
743 
744     AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
745 #endif
746 }
747 
748 
749 /*******************************************************************************
750  *
751  * FUNCTION:    AcpiDbSetMethodBreakpoint
752  *
753  * PARAMETERS:  Location            - AML offset of breakpoint
754  *              WalkState           - Current walk info
755  *              Op                  - Current Op (from parse walk)
756  *
757  * RETURN:      None
758  *
759  * DESCRIPTION: Set a breakpoint in a control method at the specified
760  *              AML offset
761  *
762  ******************************************************************************/
763 
764 void
765 AcpiDbSetMethodBreakpoint (
766     char                    *Location,
767     ACPI_WALK_STATE         *WalkState,
768     ACPI_PARSE_OBJECT       *Op)
769 {
770     UINT32                  Address;
771 
772 
773     if (!Op)
774     {
775         AcpiOsPrintf ("There is no method currently executing\n");
776         return;
777     }
778 
779     /* Get and verify the breakpoint address */
780 
781     Address = ACPI_STRTOUL (Location, NULL, 16);
782     if (Address <= Op->Common.AmlOffset)
783     {
784         AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
785             Address, Op->Common.AmlOffset);
786     }
787 
788     /* Save breakpoint in current walk */
789 
790     WalkState->UserBreakpoint = Address;
791     AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
792 }
793 
794 
795 /*******************************************************************************
796  *
797  * FUNCTION:    AcpiDbSetMethodCallBreakpoint
798  *
799  * PARAMETERS:  Op                  - Current Op (from parse walk)
800  *
801  * RETURN:      None
802  *
803  * DESCRIPTION: Set a breakpoint in a control method at the specified
804  *              AML offset
805  *
806  ******************************************************************************/
807 
808 void
809 AcpiDbSetMethodCallBreakpoint (
810     ACPI_PARSE_OBJECT       *Op)
811 {
812 
813 
814     if (!Op)
815     {
816         AcpiOsPrintf ("There is no method currently executing\n");
817         return;
818     }
819 
820     AcpiGbl_StepToNextCall = TRUE;
821 }
822 
823 
824 /*******************************************************************************
825  *
826  * FUNCTION:    AcpiDbDisassembleAml
827  *
828  * PARAMETERS:  Statements          - Number of statements to disassemble
829  *              Op                  - Current Op (from parse walk)
830  *
831  * RETURN:      None
832  *
833  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
834  *              of statements specified.
835  *
836  ******************************************************************************/
837 
838 void
839 AcpiDbDisassembleAml (
840     char                    *Statements,
841     ACPI_PARSE_OBJECT       *Op)
842 {
843     UINT32                  NumStatements = 8;
844 
845 
846     if (!Op)
847     {
848         AcpiOsPrintf ("There is no method currently executing\n");
849         return;
850     }
851 
852     if (Statements)
853     {
854         NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
855     }
856 
857     AcpiDmDisassemble (NULL, Op, NumStatements);
858 }
859 
860 
861 /*******************************************************************************
862  *
863  * FUNCTION:    AcpiDbDisassembleMethod
864  *
865  * PARAMETERS:  Name            - Name of control method
866  *
867  * RETURN:      None
868  *
869  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
870  *              of statements specified.
871  *
872  ******************************************************************************/
873 
874 ACPI_STATUS
875 AcpiDbDisassembleMethod (
876     char                    *Name)
877 {
878     ACPI_STATUS             Status;
879     ACPI_PARSE_OBJECT       *Op;
880     ACPI_WALK_STATE         *WalkState;
881     ACPI_OPERAND_OBJECT     *ObjDesc;
882     ACPI_NAMESPACE_NODE     *Method;
883 
884 
885     Method = AcpiDbConvertToNode (Name);
886     if (!Method)
887     {
888         return (AE_BAD_PARAMETER);
889     }
890 
891     ObjDesc = Method->Object;
892 
893     Op = AcpiPsCreateScopeOp ();
894     if (!Op)
895     {
896         return (AE_NO_MEMORY);
897     }
898 
899     /* Create and initialize a new walk state */
900 
901     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
902     if (!WalkState)
903     {
904         return (AE_NO_MEMORY);
905     }
906 
907     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
908                     ObjDesc->Method.AmlStart,
909                     ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
910     if (ACPI_FAILURE (Status))
911     {
912         return (Status);
913     }
914 
915     /* Parse the AML */
916 
917     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
918     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
919     Status = AcpiPsParseAml (WalkState);
920 
921     AcpiDmDisassemble (NULL, Op, 0);
922     AcpiPsDeleteParseTree (Op);
923     return (AE_OK);
924 }
925 
926 
927 /*******************************************************************************
928  *
929  * FUNCTION:    AcpiDbDumpNamespace
930  *
931  * PARAMETERS:  StartArg        - Node to begin namespace dump
932  *              DepthArg        - Maximum tree depth to be dumped
933  *
934  * RETURN:      None
935  *
936  * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
937  *              with type and other information.
938  *
939  ******************************************************************************/
940 
941 void
942 AcpiDbDumpNamespace (
943     char                    *StartArg,
944     char                    *DepthArg)
945 {
946     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
947     UINT32                  MaxDepth = ACPI_UINT32_MAX;
948 
949 
950     /* No argument given, just start at the root and dump entire namespace */
951 
952     if (StartArg)
953     {
954         SubtreeEntry = AcpiDbConvertToNode (StartArg);
955         if (!SubtreeEntry)
956         {
957             return;
958         }
959 
960         /* Now we can check for the depth argument */
961 
962         if (DepthArg)
963         {
964             MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
965         }
966     }
967 
968     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
969     AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
970         ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
971 
972     /* Display the subtree */
973 
974     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
975     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
976         ACPI_OWNER_ID_MAX, SubtreeEntry);
977     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
978 }
979 
980 
981 /*******************************************************************************
982  *
983  * FUNCTION:    AcpiDbDumpNamespaceByOwner
984  *
985  * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
986  *              DepthArg        - Maximum tree depth to be dumped
987  *
988  * RETURN:      None
989  *
990  * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
991  *
992  ******************************************************************************/
993 
994 void
995 AcpiDbDumpNamespaceByOwner (
996     char                    *OwnerArg,
997     char                    *DepthArg)
998 {
999     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
1000     UINT32                  MaxDepth = ACPI_UINT32_MAX;
1001     ACPI_OWNER_ID           OwnerId;
1002 
1003 
1004     OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
1005 
1006     /* Now we can check for the depth argument */
1007 
1008     if (DepthArg)
1009     {
1010         MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
1011     }
1012 
1013     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1014     AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
1015 
1016     /* Display the subtree */
1017 
1018     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1019     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
1020         SubtreeEntry);
1021     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1022 }
1023 
1024 
1025 /*******************************************************************************
1026  *
1027  * FUNCTION:    AcpiDbSendNotify
1028  *
1029  * PARAMETERS:  Name            - Name of ACPI object to send the notify to
1030  *              Value           - Value of the notify to send.
1031  *
1032  * RETURN:      None
1033  *
1034  * DESCRIPTION: Send an ACPI notification.  The value specified is sent to the
1035  *              named object as an ACPI notify.
1036  *
1037  ******************************************************************************/
1038 
1039 void
1040 AcpiDbSendNotify (
1041     char                    *Name,
1042     UINT32                  Value)
1043 {
1044     ACPI_NAMESPACE_NODE     *Node;
1045     ACPI_STATUS             Status;
1046 
1047 
1048     /* Translate name to an Named object */
1049 
1050     Node = AcpiDbConvertToNode (Name);
1051     if (!Node)
1052     {
1053         return;
1054     }
1055 
1056     /* Decode Named object type */
1057 
1058     switch (Node->Type)
1059     {
1060     case ACPI_TYPE_DEVICE:
1061     case ACPI_TYPE_THERMAL:
1062 
1063          /* Send the notify */
1064 
1065         Status = AcpiEvQueueNotifyRequest (Node, Value);
1066         if (ACPI_FAILURE (Status))
1067         {
1068             AcpiOsPrintf ("Could not queue notify\n");
1069         }
1070         break;
1071 
1072     default:
1073         AcpiOsPrintf ("Named object is not a device or a thermal object\n");
1074         break;
1075     }
1076 }
1077 
1078 
1079 /*******************************************************************************
1080  *
1081  * FUNCTION:    AcpiDbSetMethodData
1082  *
1083  * PARAMETERS:  TypeArg         - L for local, A for argument
1084  *              IndexArg        - which one
1085  *              ValueArg        - Value to set.
1086  *
1087  * RETURN:      None
1088  *
1089  * DESCRIPTION: Set a local or argument for the running control method.
1090  *              NOTE: only object supported is Number.
1091  *
1092  ******************************************************************************/
1093 
1094 void
1095 AcpiDbSetMethodData (
1096     char                    *TypeArg,
1097     char                    *IndexArg,
1098     char                    *ValueArg)
1099 {
1100     char                    Type;
1101     UINT32                  Index;
1102     UINT32                  Value;
1103     ACPI_WALK_STATE         *WalkState;
1104     ACPI_OPERAND_OBJECT     *ObjDesc;
1105     ACPI_STATUS             Status;
1106     ACPI_NAMESPACE_NODE     *Node;
1107 
1108 
1109     /* Validate TypeArg */
1110 
1111     AcpiUtStrupr (TypeArg);
1112     Type = TypeArg[0];
1113     if ((Type != 'L') &&
1114         (Type != 'A') &&
1115         (Type != 'N'))
1116     {
1117         AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
1118         return;
1119     }
1120 
1121     Value = ACPI_STRTOUL (ValueArg, NULL, 16);
1122 
1123     if (Type == 'N')
1124     {
1125         Node = AcpiDbConvertToNode (IndexArg);
1126         if (Node->Type != ACPI_TYPE_INTEGER)
1127         {
1128             AcpiOsPrintf ("Can only set Integer nodes\n");
1129             return;
1130         }
1131         ObjDesc = Node->Object;
1132         ObjDesc->Integer.Value = Value;
1133         return;
1134     }
1135 
1136     /* Get the index and value */
1137 
1138     Index = ACPI_STRTOUL (IndexArg, NULL, 16);
1139 
1140     WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
1141     if (!WalkState)
1142     {
1143         AcpiOsPrintf ("There is no method currently executing\n");
1144         return;
1145     }
1146 
1147     /* Create and initialize the new object */
1148 
1149     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
1150     if (!ObjDesc)
1151     {
1152         AcpiOsPrintf ("Could not create an internal object\n");
1153         return;
1154     }
1155 
1156     ObjDesc->Integer.Value = Value;
1157 
1158     /* Store the new object into the target */
1159 
1160     switch (Type)
1161     {
1162     case 'A':
1163 
1164         /* Set a method argument */
1165 
1166         if (Index > ACPI_METHOD_MAX_ARG)
1167         {
1168             AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
1169             goto Cleanup;
1170         }
1171 
1172         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc,
1173                     WalkState);
1174         if (ACPI_FAILURE (Status))
1175         {
1176             goto Cleanup;
1177         }
1178 
1179         ObjDesc = WalkState->Arguments[Index].Object;
1180 
1181         AcpiOsPrintf ("Arg%d: ", Index);
1182         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1183         break;
1184 
1185     case 'L':
1186 
1187         /* Set a method local */
1188 
1189         if (Index > ACPI_METHOD_MAX_LOCAL)
1190         {
1191             AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
1192             goto Cleanup;
1193         }
1194 
1195         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc,
1196                     WalkState);
1197         if (ACPI_FAILURE (Status))
1198         {
1199             goto Cleanup;
1200         }
1201 
1202         ObjDesc = WalkState->LocalVariables[Index].Object;
1203 
1204         AcpiOsPrintf ("Local%d: ", Index);
1205         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1206         break;
1207 
1208     default:
1209         break;
1210     }
1211 
1212 Cleanup:
1213     AcpiUtRemoveReference (ObjDesc);
1214 }
1215 
1216 
1217 /*******************************************************************************
1218  *
1219  * FUNCTION:    AcpiDbWalkForSpecificObjects
1220  *
1221  * PARAMETERS:  Callback from WalkNamespace
1222  *
1223  * RETURN:      Status
1224  *
1225  * DESCRIPTION: Display short info about objects in the namespace
1226  *
1227  ******************************************************************************/
1228 
1229 static ACPI_STATUS
1230 AcpiDbWalkForSpecificObjects (
1231     ACPI_HANDLE             ObjHandle,
1232     UINT32                  NestingLevel,
1233     void                    *Context,
1234     void                    **ReturnValue)
1235 {
1236     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
1237     ACPI_BUFFER             Buffer;
1238     ACPI_STATUS             Status;
1239 
1240 
1241     Info->Count++;
1242 
1243     /* Get and display the full pathname to this object */
1244 
1245     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1246     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1247     if (ACPI_FAILURE (Status))
1248     {
1249         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1250         return (AE_OK);
1251     }
1252 
1253     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1254     ACPI_FREE (Buffer.Pointer);
1255 
1256     /* Dump short info about the object */
1257 
1258     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1259     return (AE_OK);
1260 }
1261 
1262 
1263 /*******************************************************************************
1264  *
1265  * FUNCTION:    AcpiDbDisplayObjects
1266  *
1267  * PARAMETERS:  ObjTypeArg          - Type of object to display
1268  *              DisplayCountArg     - Max depth to display
1269  *
1270  * RETURN:      None
1271  *
1272  * DESCRIPTION: Display objects in the namespace of the requested type
1273  *
1274  ******************************************************************************/
1275 
1276 ACPI_STATUS
1277 AcpiDbDisplayObjects (
1278     char                    *ObjTypeArg,
1279     char                    *DisplayCountArg)
1280 {
1281     ACPI_WALK_INFO          Info;
1282     ACPI_OBJECT_TYPE        Type;
1283 
1284 
1285     /* Get the object type */
1286 
1287     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1288     if (Type == ACPI_TYPE_NOT_FOUND)
1289     {
1290         AcpiOsPrintf ("Invalid or unsupported argument\n");
1291         return (AE_OK);
1292     }
1293 
1294     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1295     AcpiOsPrintf (
1296         "Objects of type [%s] defined in the current ACPI Namespace:\n",
1297         AcpiUtGetTypeName (Type));
1298 
1299     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1300 
1301     Info.Count = 0;
1302     Info.OwnerId = ACPI_OWNER_ID_MAX;
1303     Info.DebugLevel = ACPI_UINT32_MAX;
1304     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1305 
1306     /* Walk the namespace from the root */
1307 
1308     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1309                 AcpiDbWalkForSpecificObjects, (void *) &Info, NULL);
1310 
1311     AcpiOsPrintf (
1312         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1313         Info.Count, AcpiUtGetTypeName (Type));
1314 
1315     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1316     return (AE_OK);
1317 }
1318 
1319 
1320 /*******************************************************************************
1321  *
1322  * FUNCTION:    AcpiDbWalkAndMatchName
1323  *
1324  * PARAMETERS:  Callback from WalkNamespace
1325  *
1326  * RETURN:      Status
1327  *
1328  * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
1329  *              are supported -- '?' matches any character.
1330  *
1331  ******************************************************************************/
1332 
1333 static ACPI_STATUS
1334 AcpiDbWalkAndMatchName (
1335     ACPI_HANDLE             ObjHandle,
1336     UINT32                  NestingLevel,
1337     void                    *Context,
1338     void                    **ReturnValue)
1339 {
1340     ACPI_STATUS             Status;
1341     char                    *RequestedName = (char *) Context;
1342     UINT32                  i;
1343     ACPI_BUFFER             Buffer;
1344     ACPI_WALK_INFO          Info;
1345 
1346 
1347     /* Check for a name match */
1348 
1349     for (i = 0; i < 4; i++)
1350     {
1351         /* Wildcard support */
1352 
1353         if ((RequestedName[i] != '?') &&
1354             (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1355         {
1356             /* No match, just exit */
1357 
1358             return (AE_OK);
1359         }
1360     }
1361 
1362     /* Get the full pathname to this object */
1363 
1364     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1365     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1366     if (ACPI_FAILURE (Status))
1367     {
1368         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1369     }
1370     else
1371     {
1372         Info.OwnerId = ACPI_OWNER_ID_MAX;
1373         Info.DebugLevel = ACPI_UINT32_MAX;
1374         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1375 
1376         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1377         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1378         ACPI_FREE (Buffer.Pointer);
1379     }
1380 
1381     return (AE_OK);
1382 }
1383 
1384 
1385 /*******************************************************************************
1386  *
1387  * FUNCTION:    AcpiDbFindNameInNamespace
1388  *
1389  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
1390  *                                wildcards are supported.
1391  *
1392  * RETURN:      None
1393  *
1394  * DESCRIPTION: Search the namespace for a given name (with wildcards)
1395  *
1396  ******************************************************************************/
1397 
1398 ACPI_STATUS
1399 AcpiDbFindNameInNamespace (
1400     char                    *NameArg)
1401 {
1402     char                    AcpiName[5] = "____";
1403     char                    *AcpiNamePtr = AcpiName;
1404 
1405 
1406     if (ACPI_STRLEN (NameArg) > 4)
1407     {
1408         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1409         return (AE_OK);
1410     }
1411 
1412     /* Pad out name with underscores as necessary to create a 4-char name */
1413 
1414     AcpiUtStrupr (NameArg);
1415     while (*NameArg)
1416     {
1417         *AcpiNamePtr = *NameArg;
1418         AcpiNamePtr++;
1419         NameArg++;
1420     }
1421 
1422     /* Walk the namespace from the root */
1423 
1424     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1425                         AcpiDbWalkAndMatchName, AcpiName, NULL);
1426 
1427     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1428     return (AE_OK);
1429 }
1430 
1431 
1432 /*******************************************************************************
1433  *
1434  * FUNCTION:    AcpiDbSetScope
1435  *
1436  * PARAMETERS:  Name                - New scope path
1437  *
1438  * RETURN:      Status
1439  *
1440  * DESCRIPTION: Set the "current scope" as maintained by this utility.
1441  *              The scope is used as a prefix to ACPI paths.
1442  *
1443  ******************************************************************************/
1444 
1445 void
1446 AcpiDbSetScope (
1447     char                    *Name)
1448 {
1449     ACPI_STATUS             Status;
1450     ACPI_NAMESPACE_NODE     *Node;
1451 
1452 
1453     if (!Name || Name[0] == 0)
1454     {
1455         AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1456         return;
1457     }
1458 
1459     AcpiDbPrepNamestring (Name);
1460 
1461     if (Name[0] == '\\')
1462     {
1463         /* Validate new scope from the root */
1464 
1465         Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
1466                     &Node);
1467         if (ACPI_FAILURE (Status))
1468         {
1469             goto ErrorExit;
1470         }
1471 
1472         ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1473         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1474     }
1475     else
1476     {
1477         /* Validate new scope relative to old scope */
1478 
1479         Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
1480                     &Node);
1481         if (ACPI_FAILURE (Status))
1482         {
1483             goto ErrorExit;
1484         }
1485 
1486         ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1487         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1488     }
1489 
1490     AcpiGbl_DbScopeNode = Node;
1491     AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1492     return;
1493 
1494 ErrorExit:
1495 
1496     AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1497         Name, AcpiFormatException (Status));
1498 }
1499 
1500 
1501 /*******************************************************************************
1502  *
1503  * FUNCTION:    AcpiDmCompareAmlResources
1504  *
1505  * PARAMETERS:  Aml1Buffer          - Contains first resource list
1506  *              Aml1BufferLength    - Length of first resource list
1507  *              Aml2Buffer          - Contains second resource list
1508  *              Aml2BufferLength    - Length of second resource list
1509  *
1510  * RETURN:      None
1511  *
1512  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1513  *              order to isolate a miscompare to an individual resource)
1514  *
1515  ******************************************************************************/
1516 
1517 static void
1518 AcpiDmCompareAmlResources (
1519     UINT8                   *Aml1Buffer,
1520     ACPI_RSDESC_SIZE        Aml1BufferLength,
1521     UINT8                   *Aml2Buffer,
1522     ACPI_RSDESC_SIZE        Aml2BufferLength)
1523 {
1524     UINT8                   *Aml1;
1525     UINT8                   *Aml2;
1526     ACPI_RSDESC_SIZE        Aml1Length;
1527     ACPI_RSDESC_SIZE        Aml2Length;
1528     ACPI_RSDESC_SIZE        Offset = 0;
1529     UINT8                   ResourceType;
1530     UINT32                  Count = 0;
1531 
1532 
1533     /* Compare overall buffer sizes (may be different due to size rounding) */
1534 
1535     if (Aml1BufferLength != Aml2BufferLength)
1536     {
1537         AcpiOsPrintf (
1538             "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1539             Aml1BufferLength, Aml2BufferLength);
1540     }
1541 
1542     Aml1 = Aml1Buffer;
1543     Aml2 = Aml2Buffer;
1544 
1545     /* Walk the descriptor lists, comparing each descriptor */
1546 
1547     while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1548     {
1549         /* Get the lengths of each descriptor */
1550 
1551         Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1552         Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1553         ResourceType = AcpiUtGetResourceType (Aml1);
1554 
1555         /* Check for descriptor length match */
1556 
1557         if (Aml1Length != Aml2Length)
1558         {
1559             AcpiOsPrintf (
1560                 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1561                 Count, ResourceType, Offset, Aml1Length, Aml2Length);
1562         }
1563 
1564         /* Check for descriptor byte match */
1565 
1566         else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1567         {
1568             AcpiOsPrintf (
1569                 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1570                 Count, ResourceType, Offset);
1571         }
1572 
1573         /* Exit on EndTag descriptor */
1574 
1575         if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1576         {
1577             return;
1578         }
1579 
1580         /* Point to next descriptor in each buffer */
1581 
1582         Count++;
1583         Offset += Aml1Length;
1584         Aml1 += Aml1Length;
1585         Aml2 += Aml2Length;
1586     }
1587 }
1588 
1589 
1590 /*******************************************************************************
1591  *
1592  * FUNCTION:    AcpiDmTestResourceConversion
1593  *
1594  * PARAMETERS:  Node            - Parent device node
1595  *              Name            - resource method name (_CRS)
1596  *
1597  * RETURN:      Status
1598  *
1599  * DESCRIPTION: Compare the original AML with a conversion of the AML to
1600  *              internal resource list, then back to AML.
1601  *
1602  ******************************************************************************/
1603 
1604 static ACPI_STATUS
1605 AcpiDmTestResourceConversion (
1606     ACPI_NAMESPACE_NODE     *Node,
1607     char                    *Name)
1608 {
1609     ACPI_STATUS             Status;
1610     ACPI_BUFFER             ReturnObj;
1611     ACPI_BUFFER             ResourceObj;
1612     ACPI_BUFFER             NewAml;
1613     ACPI_OBJECT             *OriginalAml;
1614 
1615 
1616     AcpiOsPrintf ("Resource Conversion Comparison:\n");
1617 
1618     NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1619     ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1620     ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1621 
1622     /* Get the original _CRS AML resource template */
1623 
1624     Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1625     if (ACPI_FAILURE (Status))
1626     {
1627         AcpiOsPrintf ("Could not obtain %s: %s\n",
1628             Name, AcpiFormatException (Status));
1629         return (Status);
1630     }
1631 
1632     /* Get the AML resource template, converted to internal resource structs */
1633 
1634     Status = AcpiGetCurrentResources (Node, &ResourceObj);
1635     if (ACPI_FAILURE (Status))
1636     {
1637         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1638             AcpiFormatException (Status));
1639         goto Exit1;
1640     }
1641 
1642     /* Convert internal resource list to external AML resource template */
1643 
1644     Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1645     if (ACPI_FAILURE (Status))
1646     {
1647         AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1648             AcpiFormatException (Status));
1649         goto Exit2;
1650     }
1651 
1652     /* Compare original AML to the newly created AML resource list */
1653 
1654     OriginalAml = ReturnObj.Pointer;
1655 
1656     AcpiDmCompareAmlResources (
1657         OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
1658         NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
1659 
1660     /* Cleanup and exit */
1661 
1662     ACPI_FREE (NewAml.Pointer);
1663 Exit2:
1664     ACPI_FREE (ResourceObj.Pointer);
1665 Exit1:
1666     ACPI_FREE (ReturnObj.Pointer);
1667     return (Status);
1668 }
1669 
1670 
1671 /*******************************************************************************
1672  *
1673  * FUNCTION:    AcpiDbDisplayResources
1674  *
1675  * PARAMETERS:  ObjectArg       - String with hex value of the object
1676  *
1677  * RETURN:      None
1678  *
1679  * DESCRIPTION: Display the resource objects associated with a device.
1680  *
1681  ******************************************************************************/
1682 
1683 void
1684 AcpiDbDisplayResources (
1685     char                    *ObjectArg)
1686 {
1687     ACPI_NAMESPACE_NODE     *Node;
1688     ACPI_STATUS             Status;
1689     ACPI_BUFFER             ReturnObj;
1690 
1691 
1692     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1693     AcpiDbgLevel |= ACPI_LV_RESOURCES;
1694 
1695     /* Convert string to object pointer */
1696 
1697     Node = AcpiDbConvertToNode (ObjectArg);
1698     if (!Node)
1699     {
1700         return;
1701     }
1702 
1703     /* Prepare for a return object of arbitrary size */
1704 
1705     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1706     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1707 
1708     /* _PRT */
1709 
1710     AcpiOsPrintf ("Evaluating _PRT\n");
1711 
1712     /* Check if _PRT exists */
1713 
1714     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1715     if (ACPI_FAILURE (Status))
1716     {
1717         AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1718             AcpiFormatException (Status));
1719         goto GetCrs;
1720     }
1721 
1722     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1723     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1724 
1725     Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1726     if (ACPI_FAILURE (Status))
1727     {
1728         AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1729             AcpiFormatException (Status));
1730         goto GetCrs;
1731     }
1732 
1733     AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1734 
1735 
1736     /* _CRS */
1737 
1738 GetCrs:
1739     AcpiOsPrintf ("Evaluating _CRS\n");
1740 
1741     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1742     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1743 
1744     /* Check if _CRS exists */
1745 
1746     Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1747     if (ACPI_FAILURE (Status))
1748     {
1749         AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1750             AcpiFormatException (Status));
1751         goto GetPrs;
1752     }
1753 
1754     /* Get the _CRS resource list */
1755 
1756     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1757     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1758 
1759     Status = AcpiGetCurrentResources (Node, &ReturnObj);
1760     if (ACPI_FAILURE (Status))
1761     {
1762         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1763             AcpiFormatException (Status));
1764         goto GetPrs;
1765     }
1766 
1767     /* Dump the _CRS resource list */
1768 
1769     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1770         ReturnObj.Pointer));
1771 
1772     /*
1773      * Perform comparison of original AML to newly created AML. This tests both
1774      * the AML->Resource conversion and the Resource->Aml conversion.
1775      */
1776     Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1777 
1778     /* Execute _SRS with the resource list */
1779 
1780     Status = AcpiSetCurrentResources (Node, &ReturnObj);
1781     if (ACPI_FAILURE (Status))
1782     {
1783         AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1784             AcpiFormatException (Status));
1785         goto GetPrs;
1786     }
1787 
1788 
1789     /* _PRS */
1790 
1791 GetPrs:
1792     AcpiOsPrintf ("Evaluating _PRS\n");
1793 
1794     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1795     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1796 
1797     /* Check if _PRS exists */
1798 
1799     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1800     if (ACPI_FAILURE (Status))
1801     {
1802         AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1803             AcpiFormatException (Status));
1804         goto Cleanup;
1805     }
1806 
1807     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1808     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1809 
1810     Status = AcpiGetPossibleResources (Node, &ReturnObj);
1811     if (ACPI_FAILURE (Status))
1812     {
1813         AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1814             AcpiFormatException (Status));
1815         goto Cleanup;
1816     }
1817 
1818     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1819 
1820 Cleanup:
1821 
1822     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1823     return;
1824 }
1825 
1826 
1827 /*******************************************************************************
1828  *
1829  * FUNCTION:    AcpiDbIntegrityWalk
1830  *
1831  * PARAMETERS:  Callback from WalkNamespace
1832  *
1833  * RETURN:      Status
1834  *
1835  * DESCRIPTION: Examine one NS node for valid values.
1836  *
1837  ******************************************************************************/
1838 
1839 static ACPI_STATUS
1840 AcpiDbIntegrityWalk (
1841     ACPI_HANDLE             ObjHandle,
1842     UINT32                  NestingLevel,
1843     void                    *Context,
1844     void                    **ReturnValue)
1845 {
1846     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1847     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1848     ACPI_OPERAND_OBJECT     *Object;
1849     BOOLEAN                 Alias = TRUE;
1850 
1851 
1852     Info->Nodes++;
1853 
1854     /* Verify the NS node, and dereference aliases */
1855 
1856     while (Alias)
1857     {
1858         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1859         {
1860             AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
1861                 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
1862                 ACPI_DESC_TYPE_NAMED);
1863             return (AE_OK);
1864         }
1865 
1866         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
1867             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
1868         {
1869             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
1870         }
1871         else
1872         {
1873             Alias = FALSE;
1874         }
1875     }
1876 
1877     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1878     {
1879         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1880             Node, Node->Type);
1881         return (AE_OK);
1882     }
1883 
1884     if (!AcpiUtValidAcpiName (Node->Name.Integer))
1885     {
1886         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1887         return (AE_OK);
1888     }
1889 
1890     Object = AcpiNsGetAttachedObject (Node);
1891     if (Object)
1892     {
1893         Info->Objects++;
1894         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1895         {
1896             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1897                 Object, AcpiUtGetDescriptorName (Object));
1898         }
1899     }
1900 
1901     return (AE_OK);
1902 }
1903 
1904 
1905 /*******************************************************************************
1906  *
1907  * FUNCTION:    AcpiDbCheckIntegrity
1908  *
1909  * PARAMETERS:  None
1910  *
1911  * RETURN:      None
1912  *
1913  * DESCRIPTION: Check entire namespace for data structure integrity
1914  *
1915  ******************************************************************************/
1916 
1917 void
1918 AcpiDbCheckIntegrity (
1919     void)
1920 {
1921     ACPI_INTEGRITY_INFO     Info = {0,0};
1922 
1923     /* Search all nodes in namespace */
1924 
1925     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1926                     AcpiDbIntegrityWalk, (void *) &Info, NULL);
1927 
1928     AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1929         Info.Nodes, Info.Objects);
1930 }
1931 
1932 
1933 /*******************************************************************************
1934  *
1935  * FUNCTION:    AcpiDbGenerateGpe
1936  *
1937  * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1938  *              BlockArg        - GPE block number, ascii string
1939  *                                0 or 1 for FADT GPE blocks
1940  *
1941  * RETURN:      None
1942  *
1943  * DESCRIPTION: Generate a GPE
1944  *
1945  ******************************************************************************/
1946 
1947 void
1948 AcpiDbGenerateGpe (
1949     char                    *GpeArg,
1950     char                    *BlockArg)
1951 {
1952     UINT32                  BlockNumber;
1953     UINT32                  GpeNumber;
1954     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1955 
1956 
1957     GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1958     BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1959 
1960 
1961     GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1962         GpeNumber);
1963     if (!GpeEventInfo)
1964     {
1965         AcpiOsPrintf ("Invalid GPE\n");
1966         return;
1967     }
1968 
1969     (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1970 }
1971 
1972 
1973 /*******************************************************************************
1974  *
1975  * FUNCTION:    AcpiDbBusWalk
1976  *
1977  * PARAMETERS:  Callback from WalkNamespace
1978  *
1979  * RETURN:      Status
1980  *
1981  * DESCRIPTION: Display info about device objects that have a corresponding
1982  *              _PRT method.
1983  *
1984  ******************************************************************************/
1985 
1986 static ACPI_STATUS
1987 AcpiDbBusWalk (
1988     ACPI_HANDLE             ObjHandle,
1989     UINT32                  NestingLevel,
1990     void                    *Context,
1991     void                    **ReturnValue)
1992 {
1993     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1994     ACPI_STATUS             Status;
1995     ACPI_BUFFER             Buffer;
1996     ACPI_INTEGER            ADR;
1997     ACPI_DEVICE_ID          Id;
1998     ACPI_COMPATIBLE_ID_LIST *Cid;
1999     ACPI_NAMESPACE_NODE     *TempNode;
2000 
2001 
2002     /* Exit if there is no _PRT under this device */
2003 
2004     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
2005                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
2006     if (ACPI_FAILURE (Status))
2007     {
2008         return (AE_OK);
2009     }
2010 
2011     /* Get the full path to this device object */
2012 
2013     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
2014     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
2015     if (ACPI_FAILURE (Status))
2016     {
2017         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
2018         return (AE_OK);
2019     }
2020 
2021     /* Display the full path */
2022 
2023     AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer);
2024     ACPI_FREE (Buffer.Pointer);
2025 
2026     /* _PRT info */
2027 
2028     AcpiOsPrintf ("_PRT=%p", TempNode);
2029 
2030     /* Get the _ADR value */
2031 
2032     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR);
2033     if (ACPI_FAILURE (Status))
2034     {
2035         AcpiOsPrintf (" No _ADR      ");
2036     }
2037     else
2038     {
2039         AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR);
2040     }
2041 
2042     /* Get the _HID if present */
2043 
2044     Status = AcpiUtExecute_HID (Node, &Id);
2045     if (ACPI_SUCCESS (Status))
2046     {
2047         AcpiOsPrintf (" _HID=%s", Id.Value);
2048     }
2049     else
2050     {
2051         AcpiOsPrintf ("             ");
2052     }
2053 
2054     /* Get the _UID if present */
2055 
2056     Status = AcpiUtExecute_UID (Node, &Id);
2057     if (ACPI_SUCCESS (Status))
2058     {
2059         AcpiOsPrintf (" _UID=%s", Id.Value);
2060     }
2061 
2062     /* Get the _CID if present */
2063 
2064     Status = AcpiUtExecute_CID (Node, &Cid);
2065     if (ACPI_SUCCESS (Status))
2066     {
2067         AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value);
2068         ACPI_FREE (Cid);
2069     }
2070 
2071     AcpiOsPrintf ("\n");
2072     return (AE_OK);
2073 }
2074 
2075 
2076 /*******************************************************************************
2077  *
2078  * FUNCTION:    AcpiDbGetBusInfo
2079  *
2080  * PARAMETERS:  None
2081  *
2082  * RETURN:      None
2083  *
2084  * DESCRIPTION: Display info about system busses.
2085  *
2086  ******************************************************************************/
2087 
2088 void
2089 AcpiDbGetBusInfo (
2090     void)
2091 {
2092     /* Search all nodes in namespace */
2093 
2094     (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
2095                     AcpiDbBusWalk, NULL, NULL);
2096 }
2097 
2098 #endif /* ACPI_DEBUGGER */
2099