]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/contrib/dev/acpica/debugger/dbcmds.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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 - 2010, 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, NULL, (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, NULL, (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, NULL, (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 = AcpiUtCreateIntegerObject ((UINT64) Value);
1169     if (!ObjDesc)
1170     {
1171         AcpiOsPrintf ("Could not create an internal object\n");
1172         return;
1173     }
1174
1175     /* Store the new object into the target */
1176
1177     switch (Type)
1178     {
1179     case 'A':
1180
1181         /* Set a method argument */
1182
1183         if (Index > ACPI_METHOD_MAX_ARG)
1184         {
1185             AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
1186             goto Cleanup;
1187         }
1188
1189         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc,
1190                     WalkState);
1191         if (ACPI_FAILURE (Status))
1192         {
1193             goto Cleanup;
1194         }
1195
1196         ObjDesc = WalkState->Arguments[Index].Object;
1197
1198         AcpiOsPrintf ("Arg%d: ", Index);
1199         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1200         break;
1201
1202     case 'L':
1203
1204         /* Set a method local */
1205
1206         if (Index > ACPI_METHOD_MAX_LOCAL)
1207         {
1208             AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
1209             goto Cleanup;
1210         }
1211
1212         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc,
1213                     WalkState);
1214         if (ACPI_FAILURE (Status))
1215         {
1216             goto Cleanup;
1217         }
1218
1219         ObjDesc = WalkState->LocalVariables[Index].Object;
1220
1221         AcpiOsPrintf ("Local%d: ", Index);
1222         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1223         break;
1224
1225     default:
1226         break;
1227     }
1228
1229 Cleanup:
1230     AcpiUtRemoveReference (ObjDesc);
1231 }
1232
1233
1234 /*******************************************************************************
1235  *
1236  * FUNCTION:    AcpiDbWalkForSpecificObjects
1237  *
1238  * PARAMETERS:  Callback from WalkNamespace
1239  *
1240  * RETURN:      Status
1241  *
1242  * DESCRIPTION: Display short info about objects in the namespace
1243  *
1244  ******************************************************************************/
1245
1246 static ACPI_STATUS
1247 AcpiDbWalkForSpecificObjects (
1248     ACPI_HANDLE             ObjHandle,
1249     UINT32                  NestingLevel,
1250     void                    *Context,
1251     void                    **ReturnValue)
1252 {
1253     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
1254     ACPI_BUFFER             Buffer;
1255     ACPI_STATUS             Status;
1256
1257
1258     Info->Count++;
1259
1260     /* Get and display the full pathname to this object */
1261
1262     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1263     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1264     if (ACPI_FAILURE (Status))
1265     {
1266         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1267         return (AE_OK);
1268     }
1269
1270     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1271     ACPI_FREE (Buffer.Pointer);
1272
1273     /* Dump short info about the object */
1274
1275     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1276     return (AE_OK);
1277 }
1278
1279
1280 /*******************************************************************************
1281  *
1282  * FUNCTION:    AcpiDbDisplayObjects
1283  *
1284  * PARAMETERS:  ObjTypeArg          - Type of object to display
1285  *              DisplayCountArg     - Max depth to display
1286  *
1287  * RETURN:      None
1288  *
1289  * DESCRIPTION: Display objects in the namespace of the requested type
1290  *
1291  ******************************************************************************/
1292
1293 ACPI_STATUS
1294 AcpiDbDisplayObjects (
1295     char                    *ObjTypeArg,
1296     char                    *DisplayCountArg)
1297 {
1298     ACPI_WALK_INFO          Info;
1299     ACPI_OBJECT_TYPE        Type;
1300
1301
1302     /* Get the object type */
1303
1304     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1305     if (Type == ACPI_TYPE_NOT_FOUND)
1306     {
1307         AcpiOsPrintf ("Invalid or unsupported argument\n");
1308         return (AE_OK);
1309     }
1310
1311     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1312     AcpiOsPrintf (
1313         "Objects of type [%s] defined in the current ACPI Namespace:\n",
1314         AcpiUtGetTypeName (Type));
1315
1316     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1317
1318     Info.Count = 0;
1319     Info.OwnerId = ACPI_OWNER_ID_MAX;
1320     Info.DebugLevel = ACPI_UINT32_MAX;
1321     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1322
1323     /* Walk the namespace from the root */
1324
1325     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1326                 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
1327
1328     AcpiOsPrintf (
1329         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1330         Info.Count, AcpiUtGetTypeName (Type));
1331
1332     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1333     return (AE_OK);
1334 }
1335
1336
1337 /*******************************************************************************
1338  *
1339  * FUNCTION:    AcpiDbWalkAndMatchName
1340  *
1341  * PARAMETERS:  Callback from WalkNamespace
1342  *
1343  * RETURN:      Status
1344  *
1345  * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
1346  *              are supported -- '?' matches any character.
1347  *
1348  ******************************************************************************/
1349
1350 static ACPI_STATUS
1351 AcpiDbWalkAndMatchName (
1352     ACPI_HANDLE             ObjHandle,
1353     UINT32                  NestingLevel,
1354     void                    *Context,
1355     void                    **ReturnValue)
1356 {
1357     ACPI_STATUS             Status;
1358     char                    *RequestedName = (char *) Context;
1359     UINT32                  i;
1360     ACPI_BUFFER             Buffer;
1361     ACPI_WALK_INFO          Info;
1362
1363
1364     /* Check for a name match */
1365
1366     for (i = 0; i < 4; i++)
1367     {
1368         /* Wildcard support */
1369
1370         if ((RequestedName[i] != '?') &&
1371             (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1372         {
1373             /* No match, just exit */
1374
1375             return (AE_OK);
1376         }
1377     }
1378
1379     /* Get the full pathname to this object */
1380
1381     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1382     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1383     if (ACPI_FAILURE (Status))
1384     {
1385         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1386     }
1387     else
1388     {
1389         Info.OwnerId = ACPI_OWNER_ID_MAX;
1390         Info.DebugLevel = ACPI_UINT32_MAX;
1391         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1392
1393         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1394         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1395         ACPI_FREE (Buffer.Pointer);
1396     }
1397
1398     return (AE_OK);
1399 }
1400
1401
1402 /*******************************************************************************
1403  *
1404  * FUNCTION:    AcpiDbFindNameInNamespace
1405  *
1406  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
1407  *                                wildcards are supported.
1408  *
1409  * RETURN:      None
1410  *
1411  * DESCRIPTION: Search the namespace for a given name (with wildcards)
1412  *
1413  ******************************************************************************/
1414
1415 ACPI_STATUS
1416 AcpiDbFindNameInNamespace (
1417     char                    *NameArg)
1418 {
1419     char                    AcpiName[5] = "____";
1420     char                    *AcpiNamePtr = AcpiName;
1421
1422
1423     if (ACPI_STRLEN (NameArg) > 4)
1424     {
1425         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1426         return (AE_OK);
1427     }
1428
1429     /* Pad out name with underscores as necessary to create a 4-char name */
1430
1431     AcpiUtStrupr (NameArg);
1432     while (*NameArg)
1433     {
1434         *AcpiNamePtr = *NameArg;
1435         AcpiNamePtr++;
1436         NameArg++;
1437     }
1438
1439     /* Walk the namespace from the root */
1440
1441     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1442                         AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
1443
1444     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1445     return (AE_OK);
1446 }
1447
1448
1449 /*******************************************************************************
1450  *
1451  * FUNCTION:    AcpiDbSetScope
1452  *
1453  * PARAMETERS:  Name                - New scope path
1454  *
1455  * RETURN:      Status
1456  *
1457  * DESCRIPTION: Set the "current scope" as maintained by this utility.
1458  *              The scope is used as a prefix to ACPI paths.
1459  *
1460  ******************************************************************************/
1461
1462 void
1463 AcpiDbSetScope (
1464     char                    *Name)
1465 {
1466     ACPI_STATUS             Status;
1467     ACPI_NAMESPACE_NODE     *Node;
1468
1469
1470     if (!Name || Name[0] == 0)
1471     {
1472         AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1473         return;
1474     }
1475
1476     AcpiDbPrepNamestring (Name);
1477
1478     if (Name[0] == '\\')
1479     {
1480         /* Validate new scope from the root */
1481
1482         Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
1483                     &Node);
1484         if (ACPI_FAILURE (Status))
1485         {
1486             goto ErrorExit;
1487         }
1488
1489         ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1490         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1491     }
1492     else
1493     {
1494         /* Validate new scope relative to old scope */
1495
1496         Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
1497                     &Node);
1498         if (ACPI_FAILURE (Status))
1499         {
1500             goto ErrorExit;
1501         }
1502
1503         ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1504         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1505     }
1506
1507     AcpiGbl_DbScopeNode = Node;
1508     AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1509     return;
1510
1511 ErrorExit:
1512
1513     AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1514         Name, AcpiFormatException (Status));
1515 }
1516
1517
1518 /*******************************************************************************
1519  *
1520  * FUNCTION:    AcpiDmCompareAmlResources
1521  *
1522  * PARAMETERS:  Aml1Buffer          - Contains first resource list
1523  *              Aml1BufferLength    - Length of first resource list
1524  *              Aml2Buffer          - Contains second resource list
1525  *              Aml2BufferLength    - Length of second resource list
1526  *
1527  * RETURN:      None
1528  *
1529  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1530  *              order to isolate a miscompare to an individual resource)
1531  *
1532  ******************************************************************************/
1533
1534 static void
1535 AcpiDmCompareAmlResources (
1536     UINT8                   *Aml1Buffer,
1537     ACPI_RSDESC_SIZE        Aml1BufferLength,
1538     UINT8                   *Aml2Buffer,
1539     ACPI_RSDESC_SIZE        Aml2BufferLength)
1540 {
1541     UINT8                   *Aml1;
1542     UINT8                   *Aml2;
1543     ACPI_RSDESC_SIZE        Aml1Length;
1544     ACPI_RSDESC_SIZE        Aml2Length;
1545     ACPI_RSDESC_SIZE        Offset = 0;
1546     UINT8                   ResourceType;
1547     UINT32                  Count = 0;
1548
1549
1550     /* Compare overall buffer sizes (may be different due to size rounding) */
1551
1552     if (Aml1BufferLength != Aml2BufferLength)
1553     {
1554         AcpiOsPrintf (
1555             "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1556             Aml1BufferLength, Aml2BufferLength);
1557     }
1558
1559     Aml1 = Aml1Buffer;
1560     Aml2 = Aml2Buffer;
1561
1562     /* Walk the descriptor lists, comparing each descriptor */
1563
1564     while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1565     {
1566         /* Get the lengths of each descriptor */
1567
1568         Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1569         Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1570         ResourceType = AcpiUtGetResourceType (Aml1);
1571
1572         /* Check for descriptor length match */
1573
1574         if (Aml1Length != Aml2Length)
1575         {
1576             AcpiOsPrintf (
1577                 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1578                 Count, ResourceType, Offset, Aml1Length, Aml2Length);
1579         }
1580
1581         /* Check for descriptor byte match */
1582
1583         else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1584         {
1585             AcpiOsPrintf (
1586                 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1587                 Count, ResourceType, Offset);
1588         }
1589
1590         /* Exit on EndTag descriptor */
1591
1592         if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1593         {
1594             return;
1595         }
1596
1597         /* Point to next descriptor in each buffer */
1598
1599         Count++;
1600         Offset += Aml1Length;
1601         Aml1 += Aml1Length;
1602         Aml2 += Aml2Length;
1603     }
1604 }
1605
1606
1607 /*******************************************************************************
1608  *
1609  * FUNCTION:    AcpiDmTestResourceConversion
1610  *
1611  * PARAMETERS:  Node            - Parent device node
1612  *              Name            - resource method name (_CRS)
1613  *
1614  * RETURN:      Status
1615  *
1616  * DESCRIPTION: Compare the original AML with a conversion of the AML to
1617  *              internal resource list, then back to AML.
1618  *
1619  ******************************************************************************/
1620
1621 static ACPI_STATUS
1622 AcpiDmTestResourceConversion (
1623     ACPI_NAMESPACE_NODE     *Node,
1624     char                    *Name)
1625 {
1626     ACPI_STATUS             Status;
1627     ACPI_BUFFER             ReturnObj;
1628     ACPI_BUFFER             ResourceObj;
1629     ACPI_BUFFER             NewAml;
1630     ACPI_OBJECT             *OriginalAml;
1631
1632
1633     AcpiOsPrintf ("Resource Conversion Comparison:\n");
1634
1635     NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1636     ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1637     ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1638
1639     /* Get the original _CRS AML resource template */
1640
1641     Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1642     if (ACPI_FAILURE (Status))
1643     {
1644         AcpiOsPrintf ("Could not obtain %s: %s\n",
1645             Name, AcpiFormatException (Status));
1646         return (Status);
1647     }
1648
1649     /* Get the AML resource template, converted to internal resource structs */
1650
1651     Status = AcpiGetCurrentResources (Node, &ResourceObj);
1652     if (ACPI_FAILURE (Status))
1653     {
1654         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1655             AcpiFormatException (Status));
1656         goto Exit1;
1657     }
1658
1659     /* Convert internal resource list to external AML resource template */
1660
1661     Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1662     if (ACPI_FAILURE (Status))
1663     {
1664         AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1665             AcpiFormatException (Status));
1666         goto Exit2;
1667     }
1668
1669     /* Compare original AML to the newly created AML resource list */
1670
1671     OriginalAml = ReturnObj.Pointer;
1672
1673     AcpiDmCompareAmlResources (
1674         OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
1675         NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
1676
1677     /* Cleanup and exit */
1678
1679     ACPI_FREE (NewAml.Pointer);
1680 Exit2:
1681     ACPI_FREE (ResourceObj.Pointer);
1682 Exit1:
1683     ACPI_FREE (ReturnObj.Pointer);
1684     return (Status);
1685 }
1686
1687
1688 /*******************************************************************************
1689  *
1690  * FUNCTION:    AcpiDbDisplayResources
1691  *
1692  * PARAMETERS:  ObjectArg       - String with hex value of the object
1693  *
1694  * RETURN:      None
1695  *
1696  * DESCRIPTION: Display the resource objects associated with a device.
1697  *
1698  ******************************************************************************/
1699
1700 void
1701 AcpiDbDisplayResources (
1702     char                    *ObjectArg)
1703 {
1704     ACPI_NAMESPACE_NODE     *Node;
1705     ACPI_STATUS             Status;
1706     ACPI_BUFFER             ReturnObj;
1707
1708
1709     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1710     AcpiDbgLevel |= ACPI_LV_RESOURCES;
1711
1712     /* Convert string to object pointer */
1713
1714     Node = AcpiDbConvertToNode (ObjectArg);
1715     if (!Node)
1716     {
1717         return;
1718     }
1719
1720     /* Prepare for a return object of arbitrary size */
1721
1722     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1723     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1724
1725     /* _PRT */
1726
1727     AcpiOsPrintf ("Evaluating _PRT\n");
1728
1729     /* Check if _PRT exists */
1730
1731     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1732     if (ACPI_FAILURE (Status))
1733     {
1734         AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1735             AcpiFormatException (Status));
1736         goto GetCrs;
1737     }
1738
1739     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1740     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1741
1742     Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1743     if (ACPI_FAILURE (Status))
1744     {
1745         AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1746             AcpiFormatException (Status));
1747         goto GetCrs;
1748     }
1749
1750     AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1751
1752
1753     /* _CRS */
1754
1755 GetCrs:
1756     AcpiOsPrintf ("Evaluating _CRS\n");
1757
1758     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1759     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1760
1761     /* Check if _CRS exists */
1762
1763     Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1764     if (ACPI_FAILURE (Status))
1765     {
1766         AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1767             AcpiFormatException (Status));
1768         goto GetPrs;
1769     }
1770
1771     /* Get the _CRS resource list */
1772
1773     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1774     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1775
1776     Status = AcpiGetCurrentResources (Node, &ReturnObj);
1777     if (ACPI_FAILURE (Status))
1778     {
1779         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1780             AcpiFormatException (Status));
1781         goto GetPrs;
1782     }
1783
1784     /* Dump the _CRS resource list */
1785
1786     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1787         ReturnObj.Pointer));
1788
1789     /*
1790      * Perform comparison of original AML to newly created AML. This tests both
1791      * the AML->Resource conversion and the Resource->Aml conversion.
1792      */
1793     Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1794
1795     /* Execute _SRS with the resource list */
1796
1797     Status = AcpiSetCurrentResources (Node, &ReturnObj);
1798     if (ACPI_FAILURE (Status))
1799     {
1800         AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1801             AcpiFormatException (Status));
1802         goto GetPrs;
1803     }
1804
1805
1806     /* _PRS */
1807
1808 GetPrs:
1809     AcpiOsPrintf ("Evaluating _PRS\n");
1810
1811     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1812     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1813
1814     /* Check if _PRS exists */
1815
1816     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1817     if (ACPI_FAILURE (Status))
1818     {
1819         AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1820             AcpiFormatException (Status));
1821         goto Cleanup;
1822     }
1823
1824     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1825     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1826
1827     Status = AcpiGetPossibleResources (Node, &ReturnObj);
1828     if (ACPI_FAILURE (Status))
1829     {
1830         AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1831             AcpiFormatException (Status));
1832         goto Cleanup;
1833     }
1834
1835     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1836
1837 Cleanup:
1838
1839     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1840     return;
1841 }
1842
1843
1844 /*******************************************************************************
1845  *
1846  * FUNCTION:    AcpiDbIntegrityWalk
1847  *
1848  * PARAMETERS:  Callback from WalkNamespace
1849  *
1850  * RETURN:      Status
1851  *
1852  * DESCRIPTION: Examine one NS node for valid values.
1853  *
1854  ******************************************************************************/
1855
1856 static ACPI_STATUS
1857 AcpiDbIntegrityWalk (
1858     ACPI_HANDLE             ObjHandle,
1859     UINT32                  NestingLevel,
1860     void                    *Context,
1861     void                    **ReturnValue)
1862 {
1863     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1864     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1865     ACPI_OPERAND_OBJECT     *Object;
1866     BOOLEAN                 Alias = TRUE;
1867
1868
1869     Info->Nodes++;
1870
1871     /* Verify the NS node, and dereference aliases */
1872
1873     while (Alias)
1874     {
1875         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1876         {
1877             AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
1878                 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
1879                 ACPI_DESC_TYPE_NAMED);
1880             return (AE_OK);
1881         }
1882
1883         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
1884             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
1885         {
1886             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
1887         }
1888         else
1889         {
1890             Alias = FALSE;
1891         }
1892     }
1893
1894     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1895     {
1896         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1897             Node, Node->Type);
1898         return (AE_OK);
1899     }
1900
1901     if (!AcpiUtValidAcpiName (Node->Name.Integer))
1902     {
1903         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1904         return (AE_OK);
1905     }
1906
1907     Object = AcpiNsGetAttachedObject (Node);
1908     if (Object)
1909     {
1910         Info->Objects++;
1911         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1912         {
1913             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1914                 Object, AcpiUtGetDescriptorName (Object));
1915         }
1916     }
1917
1918     return (AE_OK);
1919 }
1920
1921
1922 /*******************************************************************************
1923  *
1924  * FUNCTION:    AcpiDbCheckIntegrity
1925  *
1926  * PARAMETERS:  None
1927  *
1928  * RETURN:      None
1929  *
1930  * DESCRIPTION: Check entire namespace for data structure integrity
1931  *
1932  ******************************************************************************/
1933
1934 void
1935 AcpiDbCheckIntegrity (
1936     void)
1937 {
1938     ACPI_INTEGRITY_INFO     Info = {0,0};
1939
1940     /* Search all nodes in namespace */
1941
1942     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1943                     AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
1944
1945     AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1946         Info.Nodes, Info.Objects);
1947 }
1948
1949
1950 /*******************************************************************************
1951  *
1952  * FUNCTION:    AcpiDbGenerateGpe
1953  *
1954  * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1955  *              BlockArg        - GPE block number, ascii string
1956  *                                0 or 1 for FADT GPE blocks
1957  *
1958  * RETURN:      None
1959  *
1960  * DESCRIPTION: Generate a GPE
1961  *
1962  ******************************************************************************/
1963
1964 void
1965 AcpiDbGenerateGpe (
1966     char                    *GpeArg,
1967     char                    *BlockArg)
1968 {
1969     UINT32                  BlockNumber;
1970     UINT32                  GpeNumber;
1971     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1972
1973
1974     GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1975     BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1976
1977
1978     GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1979         GpeNumber);
1980     if (!GpeEventInfo)
1981     {
1982         AcpiOsPrintf ("Invalid GPE\n");
1983         return;
1984     }
1985
1986     (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1987 }
1988
1989
1990 /*******************************************************************************
1991  *
1992  * FUNCTION:    AcpiDbBusWalk
1993  *
1994  * PARAMETERS:  Callback from WalkNamespace
1995  *
1996  * RETURN:      Status
1997  *
1998  * DESCRIPTION: Display info about device objects that have a corresponding
1999  *              _PRT method.
2000  *
2001  ******************************************************************************/
2002
2003 static ACPI_STATUS
2004 AcpiDbBusWalk (
2005     ACPI_HANDLE             ObjHandle,
2006     UINT32                  NestingLevel,
2007     void                    *Context,
2008     void                    **ReturnValue)
2009 {
2010     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
2011     ACPI_STATUS             Status;
2012     ACPI_BUFFER             Buffer;
2013     ACPI_NAMESPACE_NODE     *TempNode;
2014     ACPI_DEVICE_INFO        *Info;
2015     UINT32                  i;
2016
2017
2018     if ((Node->Type != ACPI_TYPE_DEVICE) &&
2019         (Node->Type != ACPI_TYPE_PROCESSOR))
2020     {
2021         return (AE_OK);
2022     }
2023
2024     /* Exit if there is no _PRT under this device */
2025
2026     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
2027                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
2028     if (ACPI_FAILURE (Status))
2029     {
2030         return (AE_OK);
2031     }
2032
2033     /* Get the full path to this device object */
2034
2035     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
2036     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
2037     if (ACPI_FAILURE (Status))
2038     {
2039         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
2040         return (AE_OK);
2041     }
2042
2043     Status = AcpiGetObjectInfo (ObjHandle, &Info);
2044     if (ACPI_FAILURE (Status))
2045     {
2046         return (AE_OK);
2047     }
2048
2049     /* Display the full path */
2050
2051     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
2052     ACPI_FREE (Buffer.Pointer);
2053
2054     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
2055     {
2056         AcpiOsPrintf ("  - Is PCI Root Bridge");
2057     }
2058     AcpiOsPrintf ("\n");
2059
2060     /* _PRT info */
2061
2062     AcpiOsPrintf ("_PRT: %p\n", TempNode);
2063
2064     /* Dump _ADR, _HID, _UID, _CID */
2065
2066     if (Info->Valid & ACPI_VALID_ADR)
2067     {
2068         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
2069     }
2070     else
2071     {
2072         AcpiOsPrintf ("_ADR: <Not Present>\n");
2073     }
2074
2075     if (Info->Valid & ACPI_VALID_HID)
2076     {
2077         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
2078     }
2079     else
2080     {
2081         AcpiOsPrintf ("_HID: <Not Present>\n");
2082     }
2083
2084     if (Info->Valid & ACPI_VALID_UID)
2085     {
2086         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
2087     }
2088     else
2089     {
2090         AcpiOsPrintf ("_UID: <Not Present>\n");
2091     }
2092
2093     if (Info->Valid & ACPI_VALID_CID)
2094     {
2095         for (i = 0; i < Info->CompatibleIdList.Count; i++)
2096         {
2097             AcpiOsPrintf ("_CID: %s\n",
2098                 Info->CompatibleIdList.Ids[i].String);
2099         }
2100     }
2101     else
2102     {
2103         AcpiOsPrintf ("_CID: <Not Present>\n");
2104     }
2105
2106     ACPI_FREE (Info);
2107     return (AE_OK);
2108 }
2109
2110
2111 /*******************************************************************************
2112  *
2113  * FUNCTION:    AcpiDbGetBusInfo
2114  *
2115  * PARAMETERS:  None
2116  *
2117  * RETURN:      None
2118  *
2119  * DESCRIPTION: Display info about system busses.
2120  *
2121  ******************************************************************************/
2122
2123 void
2124 AcpiDbGetBusInfo (
2125     void)
2126 {
2127     /* Search all nodes in namespace */
2128
2129     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
2130                     AcpiDbBusWalk, NULL, NULL, NULL);
2131 }
2132
2133 #endif /* ACPI_DEBUGGER */