]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/debugger/dbcmds.c
Merge r198489 from vendor/ncurses/dist:
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / debugger / dbcmds.c
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 <contrib/dev/acpica/include/acpi.h>
118 #include <contrib/dev/acpica/include/accommon.h>
119 #include <contrib/dev/acpica/include/acdispat.h>
120 #include <contrib/dev/acpica/include/acnamesp.h>
121 #include <contrib/dev/acpica/include/acevents.h>
122 #include <contrib/dev/acpica/include/acdebug.h>
123 #include <contrib/dev/acpica/include/acresrc.h>
124 #include <contrib/dev/acpica/include/acdisasm.h>
125 #include <contrib/dev/acpica/include/actables.h>
126 #include <contrib/dev/acpica/include/acparser.h>
127
128 #ifdef ACPI_DEBUGGER
129
130 #define _COMPONENT          ACPI_CA_DEBUGGER
131         ACPI_MODULE_NAME    ("dbcmds")
132
133
134 /* Local prototypes */
135
136 static ACPI_STATUS
137 AcpiDbIntegrityWalk (
138     ACPI_HANDLE             ObjHandle,
139     UINT32                  NestingLevel,
140     void                    *Context,
141     void                    **ReturnValue);
142
143 static ACPI_STATUS
144 AcpiDbWalkAndMatchName (
145     ACPI_HANDLE             ObjHandle,
146     UINT32                  NestingLevel,
147     void                    *Context,
148     void                    **ReturnValue);
149
150 static ACPI_STATUS
151 AcpiDbWalkForReferences (
152     ACPI_HANDLE             ObjHandle,
153     UINT32                  NestingLevel,
154     void                    *Context,
155     void                    **ReturnValue);
156
157 static ACPI_STATUS
158 AcpiDbWalkForSpecificObjects (
159     ACPI_HANDLE             ObjHandle,
160     UINT32                  NestingLevel,
161     void                    *Context,
162     void                    **ReturnValue);
163
164 static ACPI_NAMESPACE_NODE *
165 AcpiDbConvertToNode (
166     char                    *InString);
167
168 static void
169 AcpiDmCompareAmlResources (
170     UINT8                   *Aml1Buffer,
171     ACPI_RSDESC_SIZE        Aml1BufferLength,
172     UINT8                   *Aml2Buffer,
173     ACPI_RSDESC_SIZE        Aml2BufferLength);
174
175 static ACPI_STATUS
176 AcpiDmTestResourceConversion (
177     ACPI_NAMESPACE_NODE     *Node,
178     char                    *Name);
179
180
181 /*
182  * Arguments for the Objects command
183  * These object types map directly to the ACPI_TYPES
184  */
185 static ARGUMENT_INFO        AcpiDbObjectTypes [] =
186 {
187     {"ANY"},
188     {"INTEGERS"},
189     {"STRINGS"},
190     {"BUFFERS"},
191     {"PACKAGES"},
192     {"FIELDS"},
193     {"DEVICES"},
194     {"EVENTS"},
195     {"METHODS"},
196     {"MUTEXES"},
197     {"REGIONS"},
198     {"POWERRESOURCES"},
199     {"PROCESSORS"},
200     {"THERMALZONES"},
201     {"BUFFERFIELDS"},
202     {"DDBHANDLES"},
203     {"DEBUG"},
204     {"REGIONFIELDS"},
205     {"BANKFIELDS"},
206     {"INDEXFIELDS"},
207     {"REFERENCES"},
208     {"ALIAS"},
209     {NULL}           /* Must be null terminated */
210 };
211
212
213 /*******************************************************************************
214  *
215  * FUNCTION:    AcpiDbConvertToNode
216  *
217  * PARAMETERS:  InString        - String to convert
218  *
219  * RETURN:      Pointer to a NS node
220  *
221  * DESCRIPTION: Convert a string to a valid NS pointer.  Handles numeric or
222  *              alpha strings.
223  *
224  ******************************************************************************/
225
226 static ACPI_NAMESPACE_NODE *
227 AcpiDbConvertToNode (
228     char                    *InString)
229 {
230     ACPI_NAMESPACE_NODE     *Node;
231
232
233     if ((*InString >= 0x30) && (*InString <= 0x39))
234     {
235         /* Numeric argument, convert */
236
237         Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
238         if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
239         {
240             AcpiOsPrintf ("Address %p is invalid in this address space\n",
241                 Node);
242             return (NULL);
243         }
244
245         /* Make sure pointer is valid NS node */
246
247         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
248         {
249             AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
250                     Node, AcpiUtGetDescriptorName (Node));
251             return (NULL);
252         }
253     }
254     else
255     {
256         /* Alpha argument */
257         /* The parameter is a name string that must be resolved to a
258          * Named obj
259          */
260         Node = AcpiDbLocalNsLookup (InString);
261         if (!Node)
262         {
263             Node = AcpiGbl_RootNode;
264         }
265     }
266
267     return (Node);
268 }
269
270
271 /*******************************************************************************
272  *
273  * FUNCTION:    AcpiDbSleep
274  *
275  * PARAMETERS:  ObjectArg       - Desired sleep state (0-5)
276  *
277  * RETURN:      Status
278  *
279  * DESCRIPTION: Simulate a sleep/wake sequence
280  *
281  ******************************************************************************/
282
283 ACPI_STATUS
284 AcpiDbSleep (
285     char                    *ObjectArg)
286 {
287     ACPI_STATUS             Status;
288     UINT8                   SleepState;
289
290
291     SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
292
293     AcpiOsPrintf ("**** Prepare to sleep ****\n");
294     Status = AcpiEnterSleepStatePrep (SleepState);
295     if (ACPI_FAILURE (Status))
296     {
297         return (Status);
298     }
299
300     AcpiOsPrintf ("**** Going to sleep ****\n");
301     Status = AcpiEnterSleepState (SleepState);
302     if (ACPI_FAILURE (Status))
303     {
304         return (Status);
305     }
306
307     AcpiOsPrintf ("**** returning from sleep ****\n");
308     Status = AcpiLeaveSleepState (SleepState);
309
310     return (Status);
311 }
312
313
314 /*******************************************************************************
315  *
316  * FUNCTION:    AcpiDbWalkForReferences
317  *
318  * PARAMETERS:  Callback from WalkNamespace
319  *
320  * RETURN:      Status
321  *
322  * DESCRIPTION: Check if this namespace object refers to the target object
323  *              that is passed in as the context value.
324  *
325  * Note: Currently doesn't check subobjects within the Node's object
326  *
327  ******************************************************************************/
328
329 static ACPI_STATUS
330 AcpiDbWalkForReferences (
331     ACPI_HANDLE             ObjHandle,
332     UINT32                  NestingLevel,
333     void                    *Context,
334     void                    **ReturnValue)
335 {
336     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
337     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
338
339
340     /* Check for match against the namespace node itself */
341
342     if (Node == (void *) ObjDesc)
343     {
344         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
345             AcpiUtGetNodeName (Node));
346     }
347
348     /* Check for match against the object attached to the node */
349
350     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
351     {
352         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
353             Node, AcpiUtGetNodeName (Node));
354     }
355
356     return (AE_OK);
357 }
358
359
360 /*******************************************************************************
361  *
362  * FUNCTION:    AcpiDbFindReferences
363  *
364  * PARAMETERS:  ObjectArg       - String with hex value of the object
365  *
366  * RETURN:      None
367  *
368  * DESCRIPTION: Search namespace for all references to the input object
369  *
370  ******************************************************************************/
371
372 void
373 AcpiDbFindReferences (
374     char                    *ObjectArg)
375 {
376     ACPI_OPERAND_OBJECT     *ObjDesc;
377
378
379     /* Convert string to object pointer */
380
381     ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
382
383     /* Search all nodes in namespace */
384
385     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
386                     AcpiDbWalkForReferences, (void *) ObjDesc, NULL);
387 }
388
389
390 /*******************************************************************************
391  *
392  * FUNCTION:    AcpiDbWalkForPredefinedNames
393  *
394  * PARAMETERS:  Callback from WalkNamespace
395  *
396  * RETURN:      Status
397  *
398  * DESCRIPTION: Detect and display predefined ACPI names (names that start with
399  *              an underscore)
400  *
401  ******************************************************************************/
402
403 static ACPI_STATUS
404 AcpiDbWalkForPredefinedNames (
405     ACPI_HANDLE             ObjHandle,
406     UINT32                  NestingLevel,
407     void                    *Context,
408     void                    **ReturnValue)
409 {
410     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
411     UINT32                      *Count = (UINT32 *) Context;
412     const ACPI_PREDEFINED_INFO  *Predefined;
413     const ACPI_PREDEFINED_INFO  *Package = NULL;
414     char                        *Pathname;
415
416
417     Predefined = AcpiNsCheckForPredefinedName (Node);
418     if (!Predefined)
419     {
420         return (AE_OK);
421     }
422
423     Pathname = AcpiNsGetExternalPathname (Node);
424     if (!Pathname)
425     {
426         return (AE_OK);
427     }
428
429     /* If method returns a package, the info is in the next table entry */
430
431     if (Predefined->Info.ExpectedBtypes & ACPI_BTYPE_PACKAGE)
432     {
433         Package = Predefined + 1;
434     }
435
436     AcpiOsPrintf ("%-32s arg %X ret %2.2X", Pathname,
437         Predefined->Info.ParamCount, Predefined->Info.ExpectedBtypes);
438
439     if (Package)
440     {
441         AcpiOsPrintf (" PkgType %2.2X ObjType %2.2X Count %2.2X",
442             Package->RetInfo.Type, Package->RetInfo.ObjectType1,
443             Package->RetInfo.Count1);
444     }
445
446     AcpiOsPrintf("\n");
447
448     AcpiNsCheckParameterCount (Pathname, Node, ACPI_UINT32_MAX, Predefined);
449     ACPI_FREE (Pathname);
450     (*Count)++;
451
452     return (AE_OK);
453 }
454
455
456 /*******************************************************************************
457  *
458  * FUNCTION:    AcpiDbCheckPredefinedNames
459  *
460  * PARAMETERS:  None
461  *
462  * RETURN:      None
463  *
464  * DESCRIPTION: Validate all predefined names in the namespace
465  *
466  ******************************************************************************/
467
468 void
469 AcpiDbCheckPredefinedNames (
470     void)
471 {
472     UINT32                  Count = 0;
473
474
475     /* Search all nodes in namespace */
476
477     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
478                 AcpiDbWalkForPredefinedNames, (void *) &Count, NULL);
479
480     AcpiOsPrintf ("Found %d predefined names in the namespace\n", Count);
481 }
482
483
484 /*******************************************************************************
485  *
486  * FUNCTION:    AcpiDbWalkForExecute
487  *
488  * PARAMETERS:  Callback from WalkNamespace
489  *
490  * RETURN:      Status
491  *
492  * DESCRIPTION: Batch execution module. Currently only executes predefined
493  *              ACPI names.
494  *
495  ******************************************************************************/
496
497 static ACPI_STATUS
498 AcpiDbWalkForExecute (
499     ACPI_HANDLE             ObjHandle,
500     UINT32                  NestingLevel,
501     void                    *Context,
502     void                    **ReturnValue)
503 {
504     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
505     ACPI_EXECUTE_WALK       *Info = (ACPI_EXECUTE_WALK *) Context;
506     ACPI_BUFFER             ReturnObj;
507     ACPI_STATUS             Status;
508     char                    *Pathname;
509     UINT32                  i;
510     ACPI_DEVICE_INFO        *ObjInfo;
511     ACPI_OBJECT_LIST        ParamObjects;
512     ACPI_OBJECT             Params[ACPI_METHOD_NUM_ARGS];
513     const ACPI_PREDEFINED_INFO *Predefined;
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     Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
536     if (ACPI_FAILURE (Status))
537     {
538         return (Status);
539     }
540
541     ParamObjects.Pointer = NULL;
542     ParamObjects.Count   = 0;
543
544     if (ObjInfo->Type == ACPI_TYPE_METHOD)
545     {
546         /* Setup default parameters */
547
548         for (i = 0; i < ObjInfo->ParamCount; i++)
549         {
550             Params[i].Type           = ACPI_TYPE_INTEGER;
551             Params[i].Integer.Value  = 1;
552         }
553
554         ParamObjects.Pointer     = Params;
555         ParamObjects.Count       = ObjInfo->ParamCount;
556     }
557
558     ACPI_FREE (ObjInfo);
559     ReturnObj.Pointer = NULL;
560     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
561
562     /* Do the actual method execution */
563
564     AcpiGbl_MethodExecuting = TRUE;
565
566     Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
567
568     AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status));
569     AcpiGbl_MethodExecuting = FALSE;
570     ACPI_FREE (Pathname);
571
572     /* Ignore status from method execution */
573
574     Status = AE_OK;
575
576     /* Update count, check if we have executed enough methods */
577
578     Info->Count++;
579     if (Info->Count >= Info->MaxCount)
580     {
581         Status = AE_CTRL_TERMINATE;
582     }
583
584     return (Status);
585 }
586
587
588 /*******************************************************************************
589  *
590  * FUNCTION:    AcpiDbBatchExecute
591  *
592  * PARAMETERS:  CountArg            - Max number of methods to execute
593  *
594  * RETURN:      None
595  *
596  * DESCRIPTION: Namespace batch execution. Execute predefined names in the
597  *              namespace, up to the max count, if specified.
598  *
599  ******************************************************************************/
600
601 void
602 AcpiDbBatchExecute (
603     char                    *CountArg)
604 {
605     ACPI_EXECUTE_WALK       Info;
606
607
608     Info.Count = 0;
609     Info.MaxCount = ACPI_UINT32_MAX;
610
611     if (CountArg)
612     {
613         Info.MaxCount = ACPI_STRTOUL (CountArg, NULL, 0);
614     }
615
616
617     /* Search all nodes in namespace */
618
619     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
620                 AcpiDbWalkForExecute, (void *) &Info, NULL);
621
622     AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Info.Count);
623 }
624
625
626 /*******************************************************************************
627  *
628  * FUNCTION:    AcpiDbDisplayLocks
629  *
630  * PARAMETERS:  None
631  *
632  * RETURN:      None
633  *
634  * DESCRIPTION: Display information about internal mutexes.
635  *
636  ******************************************************************************/
637
638 void
639 AcpiDbDisplayLocks (
640     void)
641 {
642     UINT32                  i;
643
644
645     for (i = 0; i < ACPI_MAX_MUTEX; i++)
646     {
647         AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
648             AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
649                 ? "Locked" : "Unlocked");
650     }
651 }
652
653
654 /*******************************************************************************
655  *
656  * FUNCTION:    AcpiDbDisplayTableInfo
657  *
658  * PARAMETERS:  TableArg        - String with name of table to be displayed
659  *
660  * RETURN:      None
661  *
662  * DESCRIPTION: Display information about loaded tables.  Current
663  *              implementation displays all loaded tables.
664  *
665  ******************************************************************************/
666
667 void
668 AcpiDbDisplayTableInfo (
669     char                    *TableArg)
670 {
671     UINT32                  i;
672     ACPI_TABLE_DESC         *TableDesc;
673     ACPI_STATUS             Status;
674
675
676     /* Walk the entire root table list */
677
678     for (i = 0; i < AcpiGbl_RootTableList.Count; i++)
679     {
680         TableDesc = &AcpiGbl_RootTableList.Tables[i];
681         AcpiOsPrintf ("%d ", i);
682
683         /* Make sure that the table is mapped */
684
685         Status = AcpiTbVerifyTable (TableDesc);
686         if (ACPI_FAILURE (Status))
687         {
688             return;
689         }
690
691         /* Dump the table header */
692
693         if (TableDesc->Pointer)
694         {
695             AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
696         }
697         else
698         {
699             /* If the pointer is null, the table has been unloaded */
700
701             ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
702                 TableDesc->Signature.Ascii));
703         }
704     }
705 }
706
707
708 /*******************************************************************************
709  *
710  * FUNCTION:    AcpiDbUnloadAcpiTable
711  *
712  * PARAMETERS:  TableArg        - Name of the table to be unloaded
713  *              InstanceArg     - Which instance of the table to unload (if
714  *                                there are multiple tables of the same type)
715  *
716  * RETURN:      Nonde
717  *
718  * DESCRIPTION: Unload an ACPI table.
719  *              Instance is not implemented
720  *
721  ******************************************************************************/
722
723 void
724 AcpiDbUnloadAcpiTable (
725     char                    *TableArg,
726     char                    *InstanceArg)
727 {
728 /* TBD: Need to reimplement for new data structures */
729
730 #if 0
731     UINT32                  i;
732     ACPI_STATUS             Status;
733
734
735     /* Search all tables for the target type */
736
737     for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
738     {
739         if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
740                 AcpiGbl_TableData[i].SigLength))
741         {
742             /* Found the table, unload it */
743
744             Status = AcpiUnloadTable (i);
745             if (ACPI_SUCCESS (Status))
746             {
747                 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
748             }
749             else
750             {
751                 AcpiOsPrintf ("%s, while unloading [%s]\n",
752                     AcpiFormatException (Status), TableArg);
753             }
754
755             return;
756         }
757     }
758
759     AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
760 #endif
761 }
762
763
764 /*******************************************************************************
765  *
766  * FUNCTION:    AcpiDbSetMethodBreakpoint
767  *
768  * PARAMETERS:  Location            - AML offset of breakpoint
769  *              WalkState           - Current walk info
770  *              Op                  - Current Op (from parse walk)
771  *
772  * RETURN:      None
773  *
774  * DESCRIPTION: Set a breakpoint in a control method at the specified
775  *              AML offset
776  *
777  ******************************************************************************/
778
779 void
780 AcpiDbSetMethodBreakpoint (
781     char                    *Location,
782     ACPI_WALK_STATE         *WalkState,
783     ACPI_PARSE_OBJECT       *Op)
784 {
785     UINT32                  Address;
786
787
788     if (!Op)
789     {
790         AcpiOsPrintf ("There is no method currently executing\n");
791         return;
792     }
793
794     /* Get and verify the breakpoint address */
795
796     Address = ACPI_STRTOUL (Location, NULL, 16);
797     if (Address <= Op->Common.AmlOffset)
798     {
799         AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
800             Address, Op->Common.AmlOffset);
801     }
802
803     /* Save breakpoint in current walk */
804
805     WalkState->UserBreakpoint = Address;
806     AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
807 }
808
809
810 /*******************************************************************************
811  *
812  * FUNCTION:    AcpiDbSetMethodCallBreakpoint
813  *
814  * PARAMETERS:  Op                  - Current Op (from parse walk)
815  *
816  * RETURN:      None
817  *
818  * DESCRIPTION: Set a breakpoint in a control method at the specified
819  *              AML offset
820  *
821  ******************************************************************************/
822
823 void
824 AcpiDbSetMethodCallBreakpoint (
825     ACPI_PARSE_OBJECT       *Op)
826 {
827
828
829     if (!Op)
830     {
831         AcpiOsPrintf ("There is no method currently executing\n");
832         return;
833     }
834
835     AcpiGbl_StepToNextCall = TRUE;
836 }
837
838
839 /*******************************************************************************
840  *
841  * FUNCTION:    AcpiDbDisassembleAml
842  *
843  * PARAMETERS:  Statements          - Number of statements to disassemble
844  *              Op                  - Current Op (from parse walk)
845  *
846  * RETURN:      None
847  *
848  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
849  *              of statements specified.
850  *
851  ******************************************************************************/
852
853 void
854 AcpiDbDisassembleAml (
855     char                    *Statements,
856     ACPI_PARSE_OBJECT       *Op)
857 {
858     UINT32                  NumStatements = 8;
859
860
861     if (!Op)
862     {
863         AcpiOsPrintf ("There is no method currently executing\n");
864         return;
865     }
866
867     if (Statements)
868     {
869         NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
870     }
871
872 #ifdef ACPI_DISASSEMBLER
873     AcpiDmDisassemble (NULL, Op, NumStatements);
874 #endif
875 }
876
877
878 /*******************************************************************************
879  *
880  * FUNCTION:    AcpiDbDisassembleMethod
881  *
882  * PARAMETERS:  Name            - Name of control method
883  *
884  * RETURN:      None
885  *
886  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
887  *              of statements specified.
888  *
889  ******************************************************************************/
890
891 ACPI_STATUS
892 AcpiDbDisassembleMethod (
893     char                    *Name)
894 {
895     ACPI_STATUS             Status;
896     ACPI_PARSE_OBJECT       *Op;
897     ACPI_WALK_STATE         *WalkState;
898     ACPI_OPERAND_OBJECT     *ObjDesc;
899     ACPI_NAMESPACE_NODE     *Method;
900
901
902     Method = AcpiDbConvertToNode (Name);
903     if (!Method)
904     {
905         return (AE_BAD_PARAMETER);
906     }
907
908     ObjDesc = Method->Object;
909
910     Op = AcpiPsCreateScopeOp ();
911     if (!Op)
912     {
913         return (AE_NO_MEMORY);
914     }
915
916     /* Create and initialize a new walk state */
917
918     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
919     if (!WalkState)
920     {
921         return (AE_NO_MEMORY);
922     }
923
924     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
925                     ObjDesc->Method.AmlStart,
926                     ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
927     if (ACPI_FAILURE (Status))
928     {
929         return (Status);
930     }
931
932     /* Parse the AML */
933
934     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
935     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
936     Status = AcpiPsParseAml (WalkState);
937
938 #ifdef ACPI_DISASSEMBLER
939     AcpiDmDisassemble (NULL, Op, 0);
940 #endif
941     AcpiPsDeleteParseTree (Op);
942     return (AE_OK);
943 }
944
945
946 /*******************************************************************************
947  *
948  * FUNCTION:    AcpiDbDumpNamespace
949  *
950  * PARAMETERS:  StartArg        - Node to begin namespace dump
951  *              DepthArg        - Maximum tree depth to be dumped
952  *
953  * RETURN:      None
954  *
955  * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
956  *              with type and other information.
957  *
958  ******************************************************************************/
959
960 void
961 AcpiDbDumpNamespace (
962     char                    *StartArg,
963     char                    *DepthArg)
964 {
965     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
966     UINT32                  MaxDepth = ACPI_UINT32_MAX;
967
968
969     /* No argument given, just start at the root and dump entire namespace */
970
971     if (StartArg)
972     {
973         SubtreeEntry = AcpiDbConvertToNode (StartArg);
974         if (!SubtreeEntry)
975         {
976             return;
977         }
978
979         /* Now we can check for the depth argument */
980
981         if (DepthArg)
982         {
983             MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
984         }
985     }
986
987     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
988     AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
989         ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
990
991     /* Display the subtree */
992
993     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
994     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
995         ACPI_OWNER_ID_MAX, SubtreeEntry);
996     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
997 }
998
999
1000 /*******************************************************************************
1001  *
1002  * FUNCTION:    AcpiDbDumpNamespaceByOwner
1003  *
1004  * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
1005  *              DepthArg        - Maximum tree depth to be dumped
1006  *
1007  * RETURN:      None
1008  *
1009  * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
1010  *
1011  ******************************************************************************/
1012
1013 void
1014 AcpiDbDumpNamespaceByOwner (
1015     char                    *OwnerArg,
1016     char                    *DepthArg)
1017 {
1018     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
1019     UINT32                  MaxDepth = ACPI_UINT32_MAX;
1020     ACPI_OWNER_ID           OwnerId;
1021
1022
1023     OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
1024
1025     /* Now we can check for the depth argument */
1026
1027     if (DepthArg)
1028     {
1029         MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
1030     }
1031
1032     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1033     AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
1034
1035     /* Display the subtree */
1036
1037     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1038     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
1039         SubtreeEntry);
1040     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1041 }
1042
1043
1044 /*******************************************************************************
1045  *
1046  * FUNCTION:    AcpiDbSendNotify
1047  *
1048  * PARAMETERS:  Name            - Name of ACPI object to send the notify to
1049  *              Value           - Value of the notify to send.
1050  *
1051  * RETURN:      None
1052  *
1053  * DESCRIPTION: Send an ACPI notification.  The value specified is sent to the
1054  *              named object as an ACPI notify.
1055  *
1056  ******************************************************************************/
1057
1058 void
1059 AcpiDbSendNotify (
1060     char                    *Name,
1061     UINT32                  Value)
1062 {
1063     ACPI_NAMESPACE_NODE     *Node;
1064     ACPI_STATUS             Status;
1065
1066
1067     /* Translate name to an Named object */
1068
1069     Node = AcpiDbConvertToNode (Name);
1070     if (!Node)
1071     {
1072         return;
1073     }
1074
1075     /* Decode Named object type */
1076
1077     switch (Node->Type)
1078     {
1079     case ACPI_TYPE_DEVICE:
1080     case ACPI_TYPE_THERMAL:
1081
1082          /* Send the notify */
1083
1084         Status = AcpiEvQueueNotifyRequest (Node, Value);
1085         if (ACPI_FAILURE (Status))
1086         {
1087             AcpiOsPrintf ("Could not queue notify\n");
1088         }
1089         break;
1090
1091     default:
1092         AcpiOsPrintf ("Named object is not a device or a thermal object\n");
1093         break;
1094     }
1095 }
1096
1097
1098 /*******************************************************************************
1099  *
1100  * FUNCTION:    AcpiDbSetMethodData
1101  *
1102  * PARAMETERS:  TypeArg         - L for local, A for argument
1103  *              IndexArg        - which one
1104  *              ValueArg        - Value to set.
1105  *
1106  * RETURN:      None
1107  *
1108  * DESCRIPTION: Set a local or argument for the running control method.
1109  *              NOTE: only object supported is Number.
1110  *
1111  ******************************************************************************/
1112
1113 void
1114 AcpiDbSetMethodData (
1115     char                    *TypeArg,
1116     char                    *IndexArg,
1117     char                    *ValueArg)
1118 {
1119     char                    Type;
1120     UINT32                  Index;
1121     UINT32                  Value;
1122     ACPI_WALK_STATE         *WalkState;
1123     ACPI_OPERAND_OBJECT     *ObjDesc;
1124     ACPI_STATUS             Status;
1125     ACPI_NAMESPACE_NODE     *Node;
1126
1127
1128     /* Validate TypeArg */
1129
1130     AcpiUtStrupr (TypeArg);
1131     Type = TypeArg[0];
1132     if ((Type != 'L') &&
1133         (Type != 'A') &&
1134         (Type != 'N'))
1135     {
1136         AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
1137         return;
1138     }
1139
1140     Value = ACPI_STRTOUL (ValueArg, NULL, 16);
1141
1142     if (Type == 'N')
1143     {
1144         Node = AcpiDbConvertToNode (IndexArg);
1145         if (Node->Type != ACPI_TYPE_INTEGER)
1146         {
1147             AcpiOsPrintf ("Can only set Integer nodes\n");
1148             return;
1149         }
1150         ObjDesc = Node->Object;
1151         ObjDesc->Integer.Value = Value;
1152         return;
1153     }
1154
1155     /* Get the index and value */
1156
1157     Index = ACPI_STRTOUL (IndexArg, NULL, 16);
1158
1159     WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
1160     if (!WalkState)
1161     {
1162         AcpiOsPrintf ("There is no method currently executing\n");
1163         return;
1164     }
1165
1166     /* Create and initialize the new object */
1167
1168     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
1169     if (!ObjDesc)
1170     {
1171         AcpiOsPrintf ("Could not create an internal object\n");
1172         return;
1173     }
1174
1175     ObjDesc->Integer.Value = Value;
1176
1177     /* Store the new object into the target */
1178
1179     switch (Type)
1180     {
1181     case 'A':
1182
1183         /* Set a method argument */
1184
1185         if (Index > ACPI_METHOD_MAX_ARG)
1186         {
1187             AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
1188             goto Cleanup;
1189         }
1190
1191         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc,
1192                     WalkState);
1193         if (ACPI_FAILURE (Status))
1194         {
1195             goto Cleanup;
1196         }
1197
1198         ObjDesc = WalkState->Arguments[Index].Object;
1199
1200         AcpiOsPrintf ("Arg%d: ", Index);
1201         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1202         break;
1203
1204     case 'L':
1205
1206         /* Set a method local */
1207
1208         if (Index > ACPI_METHOD_MAX_LOCAL)
1209         {
1210             AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
1211             goto Cleanup;
1212         }
1213
1214         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc,
1215                     WalkState);
1216         if (ACPI_FAILURE (Status))
1217         {
1218             goto Cleanup;
1219         }
1220
1221         ObjDesc = WalkState->LocalVariables[Index].Object;
1222
1223         AcpiOsPrintf ("Local%d: ", Index);
1224         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1225         break;
1226
1227     default:
1228         break;
1229     }
1230
1231 Cleanup:
1232     AcpiUtRemoveReference (ObjDesc);
1233 }
1234
1235
1236 /*******************************************************************************
1237  *
1238  * FUNCTION:    AcpiDbWalkForSpecificObjects
1239  *
1240  * PARAMETERS:  Callback from WalkNamespace
1241  *
1242  * RETURN:      Status
1243  *
1244  * DESCRIPTION: Display short info about objects in the namespace
1245  *
1246  ******************************************************************************/
1247
1248 static ACPI_STATUS
1249 AcpiDbWalkForSpecificObjects (
1250     ACPI_HANDLE             ObjHandle,
1251     UINT32                  NestingLevel,
1252     void                    *Context,
1253     void                    **ReturnValue)
1254 {
1255     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
1256     ACPI_BUFFER             Buffer;
1257     ACPI_STATUS             Status;
1258
1259
1260     Info->Count++;
1261
1262     /* Get and display the full pathname to this object */
1263
1264     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1265     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1266     if (ACPI_FAILURE (Status))
1267     {
1268         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1269         return (AE_OK);
1270     }
1271
1272     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1273     ACPI_FREE (Buffer.Pointer);
1274
1275     /* Dump short info about the object */
1276
1277     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1278     return (AE_OK);
1279 }
1280
1281
1282 /*******************************************************************************
1283  *
1284  * FUNCTION:    AcpiDbDisplayObjects
1285  *
1286  * PARAMETERS:  ObjTypeArg          - Type of object to display
1287  *              DisplayCountArg     - Max depth to display
1288  *
1289  * RETURN:      None
1290  *
1291  * DESCRIPTION: Display objects in the namespace of the requested type
1292  *
1293  ******************************************************************************/
1294
1295 ACPI_STATUS
1296 AcpiDbDisplayObjects (
1297     char                    *ObjTypeArg,
1298     char                    *DisplayCountArg)
1299 {
1300     ACPI_WALK_INFO          Info;
1301     ACPI_OBJECT_TYPE        Type;
1302
1303
1304     /* Get the object type */
1305
1306     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1307     if (Type == ACPI_TYPE_NOT_FOUND)
1308     {
1309         AcpiOsPrintf ("Invalid or unsupported argument\n");
1310         return (AE_OK);
1311     }
1312
1313     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1314     AcpiOsPrintf (
1315         "Objects of type [%s] defined in the current ACPI Namespace:\n",
1316         AcpiUtGetTypeName (Type));
1317
1318     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1319
1320     Info.Count = 0;
1321     Info.OwnerId = ACPI_OWNER_ID_MAX;
1322     Info.DebugLevel = ACPI_UINT32_MAX;
1323     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1324
1325     /* Walk the namespace from the root */
1326
1327     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1328                 AcpiDbWalkForSpecificObjects, (void *) &Info, NULL);
1329
1330     AcpiOsPrintf (
1331         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1332         Info.Count, AcpiUtGetTypeName (Type));
1333
1334     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1335     return (AE_OK);
1336 }
1337
1338
1339 /*******************************************************************************
1340  *
1341  * FUNCTION:    AcpiDbWalkAndMatchName
1342  *
1343  * PARAMETERS:  Callback from WalkNamespace
1344  *
1345  * RETURN:      Status
1346  *
1347  * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
1348  *              are supported -- '?' matches any character.
1349  *
1350  ******************************************************************************/
1351
1352 static ACPI_STATUS
1353 AcpiDbWalkAndMatchName (
1354     ACPI_HANDLE             ObjHandle,
1355     UINT32                  NestingLevel,
1356     void                    *Context,
1357     void                    **ReturnValue)
1358 {
1359     ACPI_STATUS             Status;
1360     char                    *RequestedName = (char *) Context;
1361     UINT32                  i;
1362     ACPI_BUFFER             Buffer;
1363     ACPI_WALK_INFO          Info;
1364
1365
1366     /* Check for a name match */
1367
1368     for (i = 0; i < 4; i++)
1369     {
1370         /* Wildcard support */
1371
1372         if ((RequestedName[i] != '?') &&
1373             (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1374         {
1375             /* No match, just exit */
1376
1377             return (AE_OK);
1378         }
1379     }
1380
1381     /* Get the full pathname to this object */
1382
1383     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1384     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1385     if (ACPI_FAILURE (Status))
1386     {
1387         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1388     }
1389     else
1390     {
1391         Info.OwnerId = ACPI_OWNER_ID_MAX;
1392         Info.DebugLevel = ACPI_UINT32_MAX;
1393         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1394
1395         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1396         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1397         ACPI_FREE (Buffer.Pointer);
1398     }
1399
1400     return (AE_OK);
1401 }
1402
1403
1404 /*******************************************************************************
1405  *
1406  * FUNCTION:    AcpiDbFindNameInNamespace
1407  *
1408  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
1409  *                                wildcards are supported.
1410  *
1411  * RETURN:      None
1412  *
1413  * DESCRIPTION: Search the namespace for a given name (with wildcards)
1414  *
1415  ******************************************************************************/
1416
1417 ACPI_STATUS
1418 AcpiDbFindNameInNamespace (
1419     char                    *NameArg)
1420 {
1421     char                    AcpiName[5] = "____";
1422     char                    *AcpiNamePtr = AcpiName;
1423
1424
1425     if (ACPI_STRLEN (NameArg) > 4)
1426     {
1427         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1428         return (AE_OK);
1429     }
1430
1431     /* Pad out name with underscores as necessary to create a 4-char name */
1432
1433     AcpiUtStrupr (NameArg);
1434     while (*NameArg)
1435     {
1436         *AcpiNamePtr = *NameArg;
1437         AcpiNamePtr++;
1438         NameArg++;
1439     }
1440
1441     /* Walk the namespace from the root */
1442
1443     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1444                         AcpiDbWalkAndMatchName, AcpiName, NULL);
1445
1446     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1447     return (AE_OK);
1448 }
1449
1450
1451 /*******************************************************************************
1452  *
1453  * FUNCTION:    AcpiDbSetScope
1454  *
1455  * PARAMETERS:  Name                - New scope path
1456  *
1457  * RETURN:      Status
1458  *
1459  * DESCRIPTION: Set the "current scope" as maintained by this utility.
1460  *              The scope is used as a prefix to ACPI paths.
1461  *
1462  ******************************************************************************/
1463
1464 void
1465 AcpiDbSetScope (
1466     char                    *Name)
1467 {
1468     ACPI_STATUS             Status;
1469     ACPI_NAMESPACE_NODE     *Node;
1470
1471
1472     if (!Name || Name[0] == 0)
1473     {
1474         AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1475         return;
1476     }
1477
1478     AcpiDbPrepNamestring (Name);
1479
1480     if (Name[0] == '\\')
1481     {
1482         /* Validate new scope from the root */
1483
1484         Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
1485                     &Node);
1486         if (ACPI_FAILURE (Status))
1487         {
1488             goto ErrorExit;
1489         }
1490
1491         ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1492         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1493     }
1494     else
1495     {
1496         /* Validate new scope relative to old scope */
1497
1498         Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
1499                     &Node);
1500         if (ACPI_FAILURE (Status))
1501         {
1502             goto ErrorExit;
1503         }
1504
1505         ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1506         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1507     }
1508
1509     AcpiGbl_DbScopeNode = Node;
1510     AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1511     return;
1512
1513 ErrorExit:
1514
1515     AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1516         Name, AcpiFormatException (Status));
1517 }
1518
1519
1520 /*******************************************************************************
1521  *
1522  * FUNCTION:    AcpiDmCompareAmlResources
1523  *
1524  * PARAMETERS:  Aml1Buffer          - Contains first resource list
1525  *              Aml1BufferLength    - Length of first resource list
1526  *              Aml2Buffer          - Contains second resource list
1527  *              Aml2BufferLength    - Length of second resource list
1528  *
1529  * RETURN:      None
1530  *
1531  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1532  *              order to isolate a miscompare to an individual resource)
1533  *
1534  ******************************************************************************/
1535
1536 static void
1537 AcpiDmCompareAmlResources (
1538     UINT8                   *Aml1Buffer,
1539     ACPI_RSDESC_SIZE        Aml1BufferLength,
1540     UINT8                   *Aml2Buffer,
1541     ACPI_RSDESC_SIZE        Aml2BufferLength)
1542 {
1543     UINT8                   *Aml1;
1544     UINT8                   *Aml2;
1545     ACPI_RSDESC_SIZE        Aml1Length;
1546     ACPI_RSDESC_SIZE        Aml2Length;
1547     ACPI_RSDESC_SIZE        Offset = 0;
1548     UINT8                   ResourceType;
1549     UINT32                  Count = 0;
1550
1551
1552     /* Compare overall buffer sizes (may be different due to size rounding) */
1553
1554     if (Aml1BufferLength != Aml2BufferLength)
1555     {
1556         AcpiOsPrintf (
1557             "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1558             Aml1BufferLength, Aml2BufferLength);
1559     }
1560
1561     Aml1 = Aml1Buffer;
1562     Aml2 = Aml2Buffer;
1563
1564     /* Walk the descriptor lists, comparing each descriptor */
1565
1566     while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1567     {
1568         /* Get the lengths of each descriptor */
1569
1570         Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1571         Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1572         ResourceType = AcpiUtGetResourceType (Aml1);
1573
1574         /* Check for descriptor length match */
1575
1576         if (Aml1Length != Aml2Length)
1577         {
1578             AcpiOsPrintf (
1579                 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1580                 Count, ResourceType, Offset, Aml1Length, Aml2Length);
1581         }
1582
1583         /* Check for descriptor byte match */
1584
1585         else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1586         {
1587             AcpiOsPrintf (
1588                 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1589                 Count, ResourceType, Offset);
1590         }
1591
1592         /* Exit on EndTag descriptor */
1593
1594         if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1595         {
1596             return;
1597         }
1598
1599         /* Point to next descriptor in each buffer */
1600
1601         Count++;
1602         Offset += Aml1Length;
1603         Aml1 += Aml1Length;
1604         Aml2 += Aml2Length;
1605     }
1606 }
1607
1608
1609 /*******************************************************************************
1610  *
1611  * FUNCTION:    AcpiDmTestResourceConversion
1612  *
1613  * PARAMETERS:  Node            - Parent device node
1614  *              Name            - resource method name (_CRS)
1615  *
1616  * RETURN:      Status
1617  *
1618  * DESCRIPTION: Compare the original AML with a conversion of the AML to
1619  *              internal resource list, then back to AML.
1620  *
1621  ******************************************************************************/
1622
1623 static ACPI_STATUS
1624 AcpiDmTestResourceConversion (
1625     ACPI_NAMESPACE_NODE     *Node,
1626     char                    *Name)
1627 {
1628     ACPI_STATUS             Status;
1629     ACPI_BUFFER             ReturnObj;
1630     ACPI_BUFFER             ResourceObj;
1631     ACPI_BUFFER             NewAml;
1632     ACPI_OBJECT             *OriginalAml;
1633
1634
1635     AcpiOsPrintf ("Resource Conversion Comparison:\n");
1636
1637     NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1638     ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1639     ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1640
1641     /* Get the original _CRS AML resource template */
1642
1643     Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1644     if (ACPI_FAILURE (Status))
1645     {
1646         AcpiOsPrintf ("Could not obtain %s: %s\n",
1647             Name, AcpiFormatException (Status));
1648         return (Status);
1649     }
1650
1651     /* Get the AML resource template, converted to internal resource structs */
1652
1653     Status = AcpiGetCurrentResources (Node, &ResourceObj);
1654     if (ACPI_FAILURE (Status))
1655     {
1656         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1657             AcpiFormatException (Status));
1658         goto Exit1;
1659     }
1660
1661     /* Convert internal resource list to external AML resource template */
1662
1663     Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1664     if (ACPI_FAILURE (Status))
1665     {
1666         AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1667             AcpiFormatException (Status));
1668         goto Exit2;
1669     }
1670
1671     /* Compare original AML to the newly created AML resource list */
1672
1673     OriginalAml = ReturnObj.Pointer;
1674
1675     AcpiDmCompareAmlResources (
1676         OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
1677         NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
1678
1679     /* Cleanup and exit */
1680
1681     ACPI_FREE (NewAml.Pointer);
1682 Exit2:
1683     ACPI_FREE (ResourceObj.Pointer);
1684 Exit1:
1685     ACPI_FREE (ReturnObj.Pointer);
1686     return (Status);
1687 }
1688
1689
1690 /*******************************************************************************
1691  *
1692  * FUNCTION:    AcpiDbDisplayResources
1693  *
1694  * PARAMETERS:  ObjectArg       - String with hex value of the object
1695  *
1696  * RETURN:      None
1697  *
1698  * DESCRIPTION: Display the resource objects associated with a device.
1699  *
1700  ******************************************************************************/
1701
1702 void
1703 AcpiDbDisplayResources (
1704     char                    *ObjectArg)
1705 {
1706     ACPI_NAMESPACE_NODE     *Node;
1707     ACPI_STATUS             Status;
1708     ACPI_BUFFER             ReturnObj;
1709
1710
1711     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1712     AcpiDbgLevel |= ACPI_LV_RESOURCES;
1713
1714     /* Convert string to object pointer */
1715
1716     Node = AcpiDbConvertToNode (ObjectArg);
1717     if (!Node)
1718     {
1719         return;
1720     }
1721
1722     /* Prepare for a return object of arbitrary size */
1723
1724     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1725     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1726
1727     /* _PRT */
1728
1729     AcpiOsPrintf ("Evaluating _PRT\n");
1730
1731     /* Check if _PRT exists */
1732
1733     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1734     if (ACPI_FAILURE (Status))
1735     {
1736         AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1737             AcpiFormatException (Status));
1738         goto GetCrs;
1739     }
1740
1741     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1742     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1743
1744     Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1745     if (ACPI_FAILURE (Status))
1746     {
1747         AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1748             AcpiFormatException (Status));
1749         goto GetCrs;
1750     }
1751
1752     AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1753
1754
1755     /* _CRS */
1756
1757 GetCrs:
1758     AcpiOsPrintf ("Evaluating _CRS\n");
1759
1760     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1761     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1762
1763     /* Check if _CRS exists */
1764
1765     Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1766     if (ACPI_FAILURE (Status))
1767     {
1768         AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1769             AcpiFormatException (Status));
1770         goto GetPrs;
1771     }
1772
1773     /* Get the _CRS resource list */
1774
1775     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1776     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1777
1778     Status = AcpiGetCurrentResources (Node, &ReturnObj);
1779     if (ACPI_FAILURE (Status))
1780     {
1781         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1782             AcpiFormatException (Status));
1783         goto GetPrs;
1784     }
1785
1786     /* Dump the _CRS resource list */
1787
1788     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1789         ReturnObj.Pointer));
1790
1791     /*
1792      * Perform comparison of original AML to newly created AML. This tests both
1793      * the AML->Resource conversion and the Resource->Aml conversion.
1794      */
1795     Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1796
1797     /* Execute _SRS with the resource list */
1798
1799     Status = AcpiSetCurrentResources (Node, &ReturnObj);
1800     if (ACPI_FAILURE (Status))
1801     {
1802         AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1803             AcpiFormatException (Status));
1804         goto GetPrs;
1805     }
1806
1807
1808     /* _PRS */
1809
1810 GetPrs:
1811     AcpiOsPrintf ("Evaluating _PRS\n");
1812
1813     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1814     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1815
1816     /* Check if _PRS exists */
1817
1818     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1819     if (ACPI_FAILURE (Status))
1820     {
1821         AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1822             AcpiFormatException (Status));
1823         goto Cleanup;
1824     }
1825
1826     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1827     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1828
1829     Status = AcpiGetPossibleResources (Node, &ReturnObj);
1830     if (ACPI_FAILURE (Status))
1831     {
1832         AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1833             AcpiFormatException (Status));
1834         goto Cleanup;
1835     }
1836
1837     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1838
1839 Cleanup:
1840
1841     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1842     return;
1843 }
1844
1845
1846 /*******************************************************************************
1847  *
1848  * FUNCTION:    AcpiDbIntegrityWalk
1849  *
1850  * PARAMETERS:  Callback from WalkNamespace
1851  *
1852  * RETURN:      Status
1853  *
1854  * DESCRIPTION: Examine one NS node for valid values.
1855  *
1856  ******************************************************************************/
1857
1858 static ACPI_STATUS
1859 AcpiDbIntegrityWalk (
1860     ACPI_HANDLE             ObjHandle,
1861     UINT32                  NestingLevel,
1862     void                    *Context,
1863     void                    **ReturnValue)
1864 {
1865     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1866     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1867     ACPI_OPERAND_OBJECT     *Object;
1868     BOOLEAN                 Alias = TRUE;
1869
1870
1871     Info->Nodes++;
1872
1873     /* Verify the NS node, and dereference aliases */
1874
1875     while (Alias)
1876     {
1877         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1878         {
1879             AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
1880                 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
1881                 ACPI_DESC_TYPE_NAMED);
1882             return (AE_OK);
1883         }
1884
1885         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
1886             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
1887         {
1888             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
1889         }
1890         else
1891         {
1892             Alias = FALSE;
1893         }
1894     }
1895
1896     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1897     {
1898         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1899             Node, Node->Type);
1900         return (AE_OK);
1901     }
1902
1903     if (!AcpiUtValidAcpiName (Node->Name.Integer))
1904     {
1905         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1906         return (AE_OK);
1907     }
1908
1909     Object = AcpiNsGetAttachedObject (Node);
1910     if (Object)
1911     {
1912         Info->Objects++;
1913         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1914         {
1915             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1916                 Object, AcpiUtGetDescriptorName (Object));
1917         }
1918     }
1919
1920     return (AE_OK);
1921 }
1922
1923
1924 /*******************************************************************************
1925  *
1926  * FUNCTION:    AcpiDbCheckIntegrity
1927  *
1928  * PARAMETERS:  None
1929  *
1930  * RETURN:      None
1931  *
1932  * DESCRIPTION: Check entire namespace for data structure integrity
1933  *
1934  ******************************************************************************/
1935
1936 void
1937 AcpiDbCheckIntegrity (
1938     void)
1939 {
1940     ACPI_INTEGRITY_INFO     Info = {0,0};
1941
1942     /* Search all nodes in namespace */
1943
1944     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1945                     AcpiDbIntegrityWalk, (void *) &Info, NULL);
1946
1947     AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1948         Info.Nodes, Info.Objects);
1949 }
1950
1951
1952 /*******************************************************************************
1953  *
1954  * FUNCTION:    AcpiDbGenerateGpe
1955  *
1956  * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1957  *              BlockArg        - GPE block number, ascii string
1958  *                                0 or 1 for FADT GPE blocks
1959  *
1960  * RETURN:      None
1961  *
1962  * DESCRIPTION: Generate a GPE
1963  *
1964  ******************************************************************************/
1965
1966 void
1967 AcpiDbGenerateGpe (
1968     char                    *GpeArg,
1969     char                    *BlockArg)
1970 {
1971     UINT32                  BlockNumber;
1972     UINT32                  GpeNumber;
1973     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1974
1975
1976     GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1977     BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1978
1979
1980     GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1981         GpeNumber);
1982     if (!GpeEventInfo)
1983     {
1984         AcpiOsPrintf ("Invalid GPE\n");
1985         return;
1986     }
1987
1988     (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1989 }
1990
1991
1992 /*******************************************************************************
1993  *
1994  * FUNCTION:    AcpiDbBusWalk
1995  *
1996  * PARAMETERS:  Callback from WalkNamespace
1997  *
1998  * RETURN:      Status
1999  *
2000  * DESCRIPTION: Display info about device objects that have a corresponding
2001  *              _PRT method.
2002  *
2003  ******************************************************************************/
2004
2005 static ACPI_STATUS
2006 AcpiDbBusWalk (
2007     ACPI_HANDLE             ObjHandle,
2008     UINT32                  NestingLevel,
2009     void                    *Context,
2010     void                    **ReturnValue)
2011 {
2012     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
2013     ACPI_STATUS             Status;
2014     ACPI_BUFFER             Buffer;
2015     ACPI_NAMESPACE_NODE     *TempNode;
2016     ACPI_DEVICE_INFO        *Info;
2017     UINT32                  i;
2018
2019
2020     if ((Node->Type != ACPI_TYPE_DEVICE) &&
2021         (Node->Type != ACPI_TYPE_PROCESSOR))
2022     {
2023         return (AE_OK);
2024     }
2025
2026     /* Exit if there is no _PRT under this device */
2027
2028     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
2029                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
2030     if (ACPI_FAILURE (Status))
2031     {
2032         return (AE_OK);
2033     }
2034
2035     /* Get the full path to this device object */
2036
2037     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
2038     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
2039     if (ACPI_FAILURE (Status))
2040     {
2041         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
2042         return (AE_OK);
2043     }
2044
2045     Status = AcpiGetObjectInfo (ObjHandle, &Info);
2046     if (ACPI_FAILURE (Status))
2047     {
2048         return (AE_OK);
2049     }
2050
2051     /* Display the full path */
2052
2053     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
2054     ACPI_FREE (Buffer.Pointer);
2055
2056     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
2057     {
2058         AcpiOsPrintf ("  - Is PCI Root Bridge");
2059     }
2060     AcpiOsPrintf ("\n");
2061
2062     /* _PRT info */
2063
2064     AcpiOsPrintf ("_PRT: %p\n", TempNode);
2065
2066     /* Dump _ADR, _HID, _UID, _CID */
2067
2068     if (Info->Valid & ACPI_VALID_ADR)
2069     {
2070         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
2071     }
2072     else
2073     {
2074         AcpiOsPrintf ("_ADR: <Not Present>\n");
2075     }
2076
2077     if (Info->Valid & ACPI_VALID_HID)
2078     {
2079         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
2080     }
2081     else
2082     {
2083         AcpiOsPrintf ("_HID: <Not Present>\n");
2084     }
2085
2086     if (Info->Valid & ACPI_VALID_UID)
2087     {
2088         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
2089     }
2090     else
2091     {
2092         AcpiOsPrintf ("_UID: <Not Present>\n");
2093     }
2094
2095     if (Info->Valid & ACPI_VALID_CID)
2096     {
2097         for (i = 0; i < Info->CompatibleIdList.Count; i++)
2098         {
2099             AcpiOsPrintf ("_CID: %s\n",
2100                 Info->CompatibleIdList.Ids[i].String);
2101         }
2102     }
2103     else
2104     {
2105         AcpiOsPrintf ("_CID: <Not Present>\n");
2106     }
2107
2108     ACPI_FREE (Info);
2109     return (AE_OK);
2110 }
2111
2112
2113 /*******************************************************************************
2114  *
2115  * FUNCTION:    AcpiDbGetBusInfo
2116  *
2117  * PARAMETERS:  None
2118  *
2119  * RETURN:      None
2120  *
2121  * DESCRIPTION: Display info about system busses.
2122  *
2123  ******************************************************************************/
2124
2125 void
2126 AcpiDbGetBusInfo (
2127     void)
2128 {
2129     /* Search all nodes in namespace */
2130
2131     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
2132                     AcpiDbBusWalk, NULL, NULL);
2133 }
2134
2135 #endif /* ACPI_DEBUGGER */