]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/acpica/lib-acpi/src/acpica/debugger/dbcmds.c
0a542d952f4572300e38474b30f154b2fe92aba6
[l4.git] / l4 / pkg / acpica / lib-acpi / src / 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 "acpi.h"
118 #include "accommon.h"
119 #include "acdispat.h"
120 #include "acnamesp.h"
121 #include "acevents.h"
122 #include "acdebug.h"
123 #include "acresrc.h"
124 #include "acdisasm.h"
125 #include "actables.h"
126 #include "acparser.h"
127
128 #ifdef ACPI_DEBUGGER
129
130 #define _COMPONENT          ACPI_CA_DEBUGGER
131         ACPI_MODULE_NAME    ("dbcmds")
132
133
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     AcpiDmDisassemble (NULL, Op, NumStatements);
873 }
874
875
876 /*******************************************************************************
877  *
878  * FUNCTION:    AcpiDbDisassembleMethod
879  *
880  * PARAMETERS:  Name            - Name of control method
881  *
882  * RETURN:      None
883  *
884  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
885  *              of statements specified.
886  *
887  ******************************************************************************/
888
889 ACPI_STATUS
890 AcpiDbDisassembleMethod (
891     char                    *Name)
892 {
893     ACPI_STATUS             Status;
894     ACPI_PARSE_OBJECT       *Op;
895     ACPI_WALK_STATE         *WalkState;
896     ACPI_OPERAND_OBJECT     *ObjDesc;
897     ACPI_NAMESPACE_NODE     *Method;
898
899
900     Method = AcpiDbConvertToNode (Name);
901     if (!Method)
902     {
903         return (AE_BAD_PARAMETER);
904     }
905
906     ObjDesc = Method->Object;
907
908     Op = AcpiPsCreateScopeOp ();
909     if (!Op)
910     {
911         return (AE_NO_MEMORY);
912     }
913
914     /* Create and initialize a new walk state */
915
916     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
917     if (!WalkState)
918     {
919         return (AE_NO_MEMORY);
920     }
921
922     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
923                     ObjDesc->Method.AmlStart,
924                     ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
925     if (ACPI_FAILURE (Status))
926     {
927         return (Status);
928     }
929
930     /* Parse the AML */
931
932     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
933     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
934     Status = AcpiPsParseAml (WalkState);
935
936     AcpiDmDisassemble (NULL, Op, 0);
937     AcpiPsDeleteParseTree (Op);
938     return (AE_OK);
939 }
940
941
942 /*******************************************************************************
943  *
944  * FUNCTION:    AcpiDbDumpNamespace
945  *
946  * PARAMETERS:  StartArg        - Node to begin namespace dump
947  *              DepthArg        - Maximum tree depth to be dumped
948  *
949  * RETURN:      None
950  *
951  * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
952  *              with type and other information.
953  *
954  ******************************************************************************/
955
956 void
957 AcpiDbDumpNamespace (
958     char                    *StartArg,
959     char                    *DepthArg)
960 {
961     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
962     UINT32                  MaxDepth = ACPI_UINT32_MAX;
963
964
965     /* No argument given, just start at the root and dump entire namespace */
966
967     if (StartArg)
968     {
969         SubtreeEntry = AcpiDbConvertToNode (StartArg);
970         if (!SubtreeEntry)
971         {
972             return;
973         }
974
975         /* Now we can check for the depth argument */
976
977         if (DepthArg)
978         {
979             MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
980         }
981     }
982
983     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
984     AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
985         ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
986
987     /* Display the subtree */
988
989     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
990     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
991         ACPI_OWNER_ID_MAX, SubtreeEntry);
992     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
993 }
994
995
996 /*******************************************************************************
997  *
998  * FUNCTION:    AcpiDbDumpNamespaceByOwner
999  *
1000  * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
1001  *              DepthArg        - Maximum tree depth to be dumped
1002  *
1003  * RETURN:      None
1004  *
1005  * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
1006  *
1007  ******************************************************************************/
1008
1009 void
1010 AcpiDbDumpNamespaceByOwner (
1011     char                    *OwnerArg,
1012     char                    *DepthArg)
1013 {
1014     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
1015     UINT32                  MaxDepth = ACPI_UINT32_MAX;
1016     ACPI_OWNER_ID           OwnerId;
1017
1018
1019     OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
1020
1021     /* Now we can check for the depth argument */
1022
1023     if (DepthArg)
1024     {
1025         MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
1026     }
1027
1028     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1029     AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
1030
1031     /* Display the subtree */
1032
1033     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1034     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
1035         SubtreeEntry);
1036     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1037 }
1038
1039
1040 /*******************************************************************************
1041  *
1042  * FUNCTION:    AcpiDbSendNotify
1043  *
1044  * PARAMETERS:  Name            - Name of ACPI object to send the notify to
1045  *              Value           - Value of the notify to send.
1046  *
1047  * RETURN:      None
1048  *
1049  * DESCRIPTION: Send an ACPI notification.  The value specified is sent to the
1050  *              named object as an ACPI notify.
1051  *
1052  ******************************************************************************/
1053
1054 void
1055 AcpiDbSendNotify (
1056     char                    *Name,
1057     UINT32                  Value)
1058 {
1059     ACPI_NAMESPACE_NODE     *Node;
1060     ACPI_STATUS             Status;
1061
1062
1063     /* Translate name to an Named object */
1064
1065     Node = AcpiDbConvertToNode (Name);
1066     if (!Node)
1067     {
1068         return;
1069     }
1070
1071     /* Decode Named object type */
1072
1073     switch (Node->Type)
1074     {
1075     case ACPI_TYPE_DEVICE:
1076     case ACPI_TYPE_THERMAL:
1077
1078          /* Send the notify */
1079
1080         Status = AcpiEvQueueNotifyRequest (Node, Value);
1081         if (ACPI_FAILURE (Status))
1082         {
1083             AcpiOsPrintf ("Could not queue notify\n");
1084         }
1085         break;
1086
1087     default:
1088         AcpiOsPrintf ("Named object is not a device or a thermal object\n");
1089         break;
1090     }
1091 }
1092
1093
1094 /*******************************************************************************
1095  *
1096  * FUNCTION:    AcpiDbSetMethodData
1097  *
1098  * PARAMETERS:  TypeArg         - L for local, A for argument
1099  *              IndexArg        - which one
1100  *              ValueArg        - Value to set.
1101  *
1102  * RETURN:      None
1103  *
1104  * DESCRIPTION: Set a local or argument for the running control method.
1105  *              NOTE: only object supported is Number.
1106  *
1107  ******************************************************************************/
1108
1109 void
1110 AcpiDbSetMethodData (
1111     char                    *TypeArg,
1112     char                    *IndexArg,
1113     char                    *ValueArg)
1114 {
1115     char                    Type;
1116     UINT32                  Index;
1117     UINT32                  Value;
1118     ACPI_WALK_STATE         *WalkState;
1119     ACPI_OPERAND_OBJECT     *ObjDesc;
1120     ACPI_STATUS             Status;
1121     ACPI_NAMESPACE_NODE     *Node;
1122
1123
1124     /* Validate TypeArg */
1125
1126     AcpiUtStrupr (TypeArg);
1127     Type = TypeArg[0];
1128     if ((Type != 'L') &&
1129         (Type != 'A') &&
1130         (Type != 'N'))
1131     {
1132         AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
1133         return;
1134     }
1135
1136     Value = ACPI_STRTOUL (ValueArg, NULL, 16);
1137
1138     if (Type == 'N')
1139     {
1140         Node = AcpiDbConvertToNode (IndexArg);
1141         if (Node->Type != ACPI_TYPE_INTEGER)
1142         {
1143             AcpiOsPrintf ("Can only set Integer nodes\n");
1144             return;
1145         }
1146         ObjDesc = Node->Object;
1147         ObjDesc->Integer.Value = Value;
1148         return;
1149     }
1150
1151     /* Get the index and value */
1152
1153     Index = ACPI_STRTOUL (IndexArg, NULL, 16);
1154
1155     WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
1156     if (!WalkState)
1157     {
1158         AcpiOsPrintf ("There is no method currently executing\n");
1159         return;
1160     }
1161
1162     /* Create and initialize the new object */
1163
1164     ObjDesc = AcpiUtCreateIntegerObject ((UINT64) Value);
1165     if (!ObjDesc)
1166     {
1167         AcpiOsPrintf ("Could not create an internal object\n");
1168         return;
1169     }
1170
1171     /* Store the new object into the target */
1172
1173     switch (Type)
1174     {
1175     case 'A':
1176
1177         /* Set a method argument */
1178
1179         if (Index > ACPI_METHOD_MAX_ARG)
1180         {
1181             AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
1182             goto Cleanup;
1183         }
1184
1185         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc,
1186                     WalkState);
1187         if (ACPI_FAILURE (Status))
1188         {
1189             goto Cleanup;
1190         }
1191
1192         ObjDesc = WalkState->Arguments[Index].Object;
1193
1194         AcpiOsPrintf ("Arg%d: ", Index);
1195         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1196         break;
1197
1198     case 'L':
1199
1200         /* Set a method local */
1201
1202         if (Index > ACPI_METHOD_MAX_LOCAL)
1203         {
1204             AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
1205             goto Cleanup;
1206         }
1207
1208         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc,
1209                     WalkState);
1210         if (ACPI_FAILURE (Status))
1211         {
1212             goto Cleanup;
1213         }
1214
1215         ObjDesc = WalkState->LocalVariables[Index].Object;
1216
1217         AcpiOsPrintf ("Local%d: ", Index);
1218         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1219         break;
1220
1221     default:
1222         break;
1223     }
1224
1225 Cleanup:
1226     AcpiUtRemoveReference (ObjDesc);
1227 }
1228
1229
1230 /*******************************************************************************
1231  *
1232  * FUNCTION:    AcpiDbWalkForSpecificObjects
1233  *
1234  * PARAMETERS:  Callback from WalkNamespace
1235  *
1236  * RETURN:      Status
1237  *
1238  * DESCRIPTION: Display short info about objects in the namespace
1239  *
1240  ******************************************************************************/
1241
1242 static ACPI_STATUS
1243 AcpiDbWalkForSpecificObjects (
1244     ACPI_HANDLE             ObjHandle,
1245     UINT32                  NestingLevel,
1246     void                    *Context,
1247     void                    **ReturnValue)
1248 {
1249     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
1250     ACPI_BUFFER             Buffer;
1251     ACPI_STATUS             Status;
1252
1253
1254     Info->Count++;
1255
1256     /* Get and display the full pathname to this object */
1257
1258     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1259     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1260     if (ACPI_FAILURE (Status))
1261     {
1262         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1263         return (AE_OK);
1264     }
1265
1266     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1267     ACPI_FREE (Buffer.Pointer);
1268
1269     /* Dump short info about the object */
1270
1271     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1272     return (AE_OK);
1273 }
1274
1275
1276 /*******************************************************************************
1277  *
1278  * FUNCTION:    AcpiDbDisplayObjects
1279  *
1280  * PARAMETERS:  ObjTypeArg          - Type of object to display
1281  *              DisplayCountArg     - Max depth to display
1282  *
1283  * RETURN:      None
1284  *
1285  * DESCRIPTION: Display objects in the namespace of the requested type
1286  *
1287  ******************************************************************************/
1288
1289 ACPI_STATUS
1290 AcpiDbDisplayObjects (
1291     char                    *ObjTypeArg,
1292     char                    *DisplayCountArg)
1293 {
1294     ACPI_WALK_INFO          Info;
1295     ACPI_OBJECT_TYPE        Type;
1296
1297
1298     /* Get the object type */
1299
1300     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1301     if (Type == ACPI_TYPE_NOT_FOUND)
1302     {
1303         AcpiOsPrintf ("Invalid or unsupported argument\n");
1304         return (AE_OK);
1305     }
1306
1307     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1308     AcpiOsPrintf (
1309         "Objects of type [%s] defined in the current ACPI Namespace:\n",
1310         AcpiUtGetTypeName (Type));
1311
1312     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1313
1314     Info.Count = 0;
1315     Info.OwnerId = ACPI_OWNER_ID_MAX;
1316     Info.DebugLevel = ACPI_UINT32_MAX;
1317     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1318
1319     /* Walk the namespace from the root */
1320
1321     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1322                 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
1323
1324     AcpiOsPrintf (
1325         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1326         Info.Count, AcpiUtGetTypeName (Type));
1327
1328     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1329     return (AE_OK);
1330 }
1331
1332
1333 /*******************************************************************************
1334  *
1335  * FUNCTION:    AcpiDbWalkAndMatchName
1336  *
1337  * PARAMETERS:  Callback from WalkNamespace
1338  *
1339  * RETURN:      Status
1340  *
1341  * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
1342  *              are supported -- '?' matches any character.
1343  *
1344  ******************************************************************************/
1345
1346 static ACPI_STATUS
1347 AcpiDbWalkAndMatchName (
1348     ACPI_HANDLE             ObjHandle,
1349     UINT32                  NestingLevel,
1350     void                    *Context,
1351     void                    **ReturnValue)
1352 {
1353     ACPI_STATUS             Status;
1354     char                    *RequestedName = (char *) Context;
1355     UINT32                  i;
1356     ACPI_BUFFER             Buffer;
1357     ACPI_WALK_INFO          Info;
1358
1359
1360     /* Check for a name match */
1361
1362     for (i = 0; i < 4; i++)
1363     {
1364         /* Wildcard support */
1365
1366         if ((RequestedName[i] != '?') &&
1367             (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1368         {
1369             /* No match, just exit */
1370
1371             return (AE_OK);
1372         }
1373     }
1374
1375     /* Get the full pathname to this object */
1376
1377     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1378     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1379     if (ACPI_FAILURE (Status))
1380     {
1381         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1382     }
1383     else
1384     {
1385         Info.OwnerId = ACPI_OWNER_ID_MAX;
1386         Info.DebugLevel = ACPI_UINT32_MAX;
1387         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1388
1389         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1390         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1391         ACPI_FREE (Buffer.Pointer);
1392     }
1393
1394     return (AE_OK);
1395 }
1396
1397
1398 /*******************************************************************************
1399  *
1400  * FUNCTION:    AcpiDbFindNameInNamespace
1401  *
1402  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
1403  *                                wildcards are supported.
1404  *
1405  * RETURN:      None
1406  *
1407  * DESCRIPTION: Search the namespace for a given name (with wildcards)
1408  *
1409  ******************************************************************************/
1410
1411 ACPI_STATUS
1412 AcpiDbFindNameInNamespace (
1413     char                    *NameArg)
1414 {
1415     char                    AcpiName[5] = "____";
1416     char                    *AcpiNamePtr = AcpiName;
1417
1418
1419     if (ACPI_STRLEN (NameArg) > 4)
1420     {
1421         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1422         return (AE_OK);
1423     }
1424
1425     /* Pad out name with underscores as necessary to create a 4-char name */
1426
1427     AcpiUtStrupr (NameArg);
1428     while (*NameArg)
1429     {
1430         *AcpiNamePtr = *NameArg;
1431         AcpiNamePtr++;
1432         NameArg++;
1433     }
1434
1435     /* Walk the namespace from the root */
1436
1437     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1438                         AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
1439
1440     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1441     return (AE_OK);
1442 }
1443
1444
1445 /*******************************************************************************
1446  *
1447  * FUNCTION:    AcpiDbSetScope
1448  *
1449  * PARAMETERS:  Name                - New scope path
1450  *
1451  * RETURN:      Status
1452  *
1453  * DESCRIPTION: Set the "current scope" as maintained by this utility.
1454  *              The scope is used as a prefix to ACPI paths.
1455  *
1456  ******************************************************************************/
1457
1458 void
1459 AcpiDbSetScope (
1460     char                    *Name)
1461 {
1462     ACPI_STATUS             Status;
1463     ACPI_NAMESPACE_NODE     *Node;
1464
1465
1466     if (!Name || Name[0] == 0)
1467     {
1468         AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1469         return;
1470     }
1471
1472     AcpiDbPrepNamestring (Name);
1473
1474     if (Name[0] == '\\')
1475     {
1476         /* Validate new scope from the root */
1477
1478         Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
1479                     &Node);
1480         if (ACPI_FAILURE (Status))
1481         {
1482             goto ErrorExit;
1483         }
1484
1485         ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1486         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1487     }
1488     else
1489     {
1490         /* Validate new scope relative to old scope */
1491
1492         Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
1493                     &Node);
1494         if (ACPI_FAILURE (Status))
1495         {
1496             goto ErrorExit;
1497         }
1498
1499         ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1500         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1501     }
1502
1503     AcpiGbl_DbScopeNode = Node;
1504     AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1505     return;
1506
1507 ErrorExit:
1508
1509     AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1510         Name, AcpiFormatException (Status));
1511 }
1512
1513
1514 /*******************************************************************************
1515  *
1516  * FUNCTION:    AcpiDmCompareAmlResources
1517  *
1518  * PARAMETERS:  Aml1Buffer          - Contains first resource list
1519  *              Aml1BufferLength    - Length of first resource list
1520  *              Aml2Buffer          - Contains second resource list
1521  *              Aml2BufferLength    - Length of second resource list
1522  *
1523  * RETURN:      None
1524  *
1525  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1526  *              order to isolate a miscompare to an individual resource)
1527  *
1528  ******************************************************************************/
1529
1530 static void
1531 AcpiDmCompareAmlResources (
1532     UINT8                   *Aml1Buffer,
1533     ACPI_RSDESC_SIZE        Aml1BufferLength,
1534     UINT8                   *Aml2Buffer,
1535     ACPI_RSDESC_SIZE        Aml2BufferLength)
1536 {
1537     UINT8                   *Aml1;
1538     UINT8                   *Aml2;
1539     ACPI_RSDESC_SIZE        Aml1Length;
1540     ACPI_RSDESC_SIZE        Aml2Length;
1541     ACPI_RSDESC_SIZE        Offset = 0;
1542     UINT8                   ResourceType;
1543     UINT32                  Count = 0;
1544
1545
1546     /* Compare overall buffer sizes (may be different due to size rounding) */
1547
1548     if (Aml1BufferLength != Aml2BufferLength)
1549     {
1550         AcpiOsPrintf (
1551             "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1552             Aml1BufferLength, Aml2BufferLength);
1553     }
1554
1555     Aml1 = Aml1Buffer;
1556     Aml2 = Aml2Buffer;
1557
1558     /* Walk the descriptor lists, comparing each descriptor */
1559
1560     while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1561     {
1562         /* Get the lengths of each descriptor */
1563
1564         Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1565         Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1566         ResourceType = AcpiUtGetResourceType (Aml1);
1567
1568         /* Check for descriptor length match */
1569
1570         if (Aml1Length != Aml2Length)
1571         {
1572             AcpiOsPrintf (
1573                 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1574                 Count, ResourceType, Offset, Aml1Length, Aml2Length);
1575         }
1576
1577         /* Check for descriptor byte match */
1578
1579         else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1580         {
1581             AcpiOsPrintf (
1582                 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1583                 Count, ResourceType, Offset);
1584         }
1585
1586         /* Exit on EndTag descriptor */
1587
1588         if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1589         {
1590             return;
1591         }
1592
1593         /* Point to next descriptor in each buffer */
1594
1595         Count++;
1596         Offset += Aml1Length;
1597         Aml1 += Aml1Length;
1598         Aml2 += Aml2Length;
1599     }
1600 }
1601
1602
1603 /*******************************************************************************
1604  *
1605  * FUNCTION:    AcpiDmTestResourceConversion
1606  *
1607  * PARAMETERS:  Node            - Parent device node
1608  *              Name            - resource method name (_CRS)
1609  *
1610  * RETURN:      Status
1611  *
1612  * DESCRIPTION: Compare the original AML with a conversion of the AML to
1613  *              internal resource list, then back to AML.
1614  *
1615  ******************************************************************************/
1616
1617 static ACPI_STATUS
1618 AcpiDmTestResourceConversion (
1619     ACPI_NAMESPACE_NODE     *Node,
1620     char                    *Name)
1621 {
1622     ACPI_STATUS             Status;
1623     ACPI_BUFFER             ReturnObj;
1624     ACPI_BUFFER             ResourceObj;
1625     ACPI_BUFFER             NewAml;
1626     ACPI_OBJECT             *OriginalAml;
1627
1628
1629     AcpiOsPrintf ("Resource Conversion Comparison:\n");
1630
1631     NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1632     ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1633     ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1634
1635     /* Get the original _CRS AML resource template */
1636
1637     Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1638     if (ACPI_FAILURE (Status))
1639     {
1640         AcpiOsPrintf ("Could not obtain %s: %s\n",
1641             Name, AcpiFormatException (Status));
1642         return (Status);
1643     }
1644
1645     /* Get the AML resource template, converted to internal resource structs */
1646
1647     Status = AcpiGetCurrentResources (Node, &ResourceObj);
1648     if (ACPI_FAILURE (Status))
1649     {
1650         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1651             AcpiFormatException (Status));
1652         goto Exit1;
1653     }
1654
1655     /* Convert internal resource list to external AML resource template */
1656
1657     Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1658     if (ACPI_FAILURE (Status))
1659     {
1660         AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1661             AcpiFormatException (Status));
1662         goto Exit2;
1663     }
1664
1665     /* Compare original AML to the newly created AML resource list */
1666
1667     OriginalAml = ReturnObj.Pointer;
1668
1669     AcpiDmCompareAmlResources (
1670         OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
1671         NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
1672
1673     /* Cleanup and exit */
1674
1675     ACPI_FREE (NewAml.Pointer);
1676 Exit2:
1677     ACPI_FREE (ResourceObj.Pointer);
1678 Exit1:
1679     ACPI_FREE (ReturnObj.Pointer);
1680     return (Status);
1681 }
1682
1683
1684 /*******************************************************************************
1685  *
1686  * FUNCTION:    AcpiDbDisplayResources
1687  *
1688  * PARAMETERS:  ObjectArg       - String with hex value of the object
1689  *
1690  * RETURN:      None
1691  *
1692  * DESCRIPTION: Display the resource objects associated with a device.
1693  *
1694  ******************************************************************************/
1695
1696 void
1697 AcpiDbDisplayResources (
1698     char                    *ObjectArg)
1699 {
1700     ACPI_NAMESPACE_NODE     *Node;
1701     ACPI_STATUS             Status;
1702     ACPI_BUFFER             ReturnObj;
1703
1704
1705     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1706     AcpiDbgLevel |= ACPI_LV_RESOURCES;
1707
1708     /* Convert string to object pointer */
1709
1710     Node = AcpiDbConvertToNode (ObjectArg);
1711     if (!Node)
1712     {
1713         return;
1714     }
1715
1716     /* Prepare for a return object of arbitrary size */
1717
1718     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1719     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1720
1721     /* _PRT */
1722
1723     AcpiOsPrintf ("Evaluating _PRT\n");
1724
1725     /* Check if _PRT exists */
1726
1727     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1728     if (ACPI_FAILURE (Status))
1729     {
1730         AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1731             AcpiFormatException (Status));
1732         goto GetCrs;
1733     }
1734
1735     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1736     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1737
1738     Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1739     if (ACPI_FAILURE (Status))
1740     {
1741         AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1742             AcpiFormatException (Status));
1743         goto GetCrs;
1744     }
1745
1746     AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1747
1748
1749     /* _CRS */
1750
1751 GetCrs:
1752     AcpiOsPrintf ("Evaluating _CRS\n");
1753
1754     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1755     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1756
1757     /* Check if _CRS exists */
1758
1759     Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1760     if (ACPI_FAILURE (Status))
1761     {
1762         AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1763             AcpiFormatException (Status));
1764         goto GetPrs;
1765     }
1766
1767     /* Get the _CRS resource list */
1768
1769     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1770     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1771
1772     Status = AcpiGetCurrentResources (Node, &ReturnObj);
1773     if (ACPI_FAILURE (Status))
1774     {
1775         AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1776             AcpiFormatException (Status));
1777         goto GetPrs;
1778     }
1779
1780     /* Dump the _CRS resource list */
1781
1782     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1783         ReturnObj.Pointer));
1784
1785     /*
1786      * Perform comparison of original AML to newly created AML. This tests both
1787      * the AML->Resource conversion and the Resource->Aml conversion.
1788      */
1789     Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1790
1791     /* Execute _SRS with the resource list */
1792
1793     Status = AcpiSetCurrentResources (Node, &ReturnObj);
1794     if (ACPI_FAILURE (Status))
1795     {
1796         AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1797             AcpiFormatException (Status));
1798         goto GetPrs;
1799     }
1800
1801
1802     /* _PRS */
1803
1804 GetPrs:
1805     AcpiOsPrintf ("Evaluating _PRS\n");
1806
1807     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1808     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1809
1810     /* Check if _PRS exists */
1811
1812     Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1813     if (ACPI_FAILURE (Status))
1814     {
1815         AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1816             AcpiFormatException (Status));
1817         goto Cleanup;
1818     }
1819
1820     ReturnObj.Pointer = AcpiGbl_DbBuffer;
1821     ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1822
1823     Status = AcpiGetPossibleResources (Node, &ReturnObj);
1824     if (ACPI_FAILURE (Status))
1825     {
1826         AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1827             AcpiFormatException (Status));
1828         goto Cleanup;
1829     }
1830
1831     AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1832
1833 Cleanup:
1834
1835     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1836     return;
1837 }
1838
1839
1840 /*******************************************************************************
1841  *
1842  * FUNCTION:    AcpiDbIntegrityWalk
1843  *
1844  * PARAMETERS:  Callback from WalkNamespace
1845  *
1846  * RETURN:      Status
1847  *
1848  * DESCRIPTION: Examine one NS node for valid values.
1849  *
1850  ******************************************************************************/
1851
1852 static ACPI_STATUS
1853 AcpiDbIntegrityWalk (
1854     ACPI_HANDLE             ObjHandle,
1855     UINT32                  NestingLevel,
1856     void                    *Context,
1857     void                    **ReturnValue)
1858 {
1859     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1860     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1861     ACPI_OPERAND_OBJECT     *Object;
1862     BOOLEAN                 Alias = TRUE;
1863
1864
1865     Info->Nodes++;
1866
1867     /* Verify the NS node, and dereference aliases */
1868
1869     while (Alias)
1870     {
1871         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1872         {
1873             AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
1874                 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
1875                 ACPI_DESC_TYPE_NAMED);
1876             return (AE_OK);
1877         }
1878
1879         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
1880             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
1881         {
1882             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
1883         }
1884         else
1885         {
1886             Alias = FALSE;
1887         }
1888     }
1889
1890     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1891     {
1892         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1893             Node, Node->Type);
1894         return (AE_OK);
1895     }
1896
1897     if (!AcpiUtValidAcpiName (Node->Name.Integer))
1898     {
1899         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1900         return (AE_OK);
1901     }
1902
1903     Object = AcpiNsGetAttachedObject (Node);
1904     if (Object)
1905     {
1906         Info->Objects++;
1907         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1908         {
1909             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1910                 Object, AcpiUtGetDescriptorName (Object));
1911         }
1912     }
1913
1914     return (AE_OK);
1915 }
1916
1917
1918 /*******************************************************************************
1919  *
1920  * FUNCTION:    AcpiDbCheckIntegrity
1921  *
1922  * PARAMETERS:  None
1923  *
1924  * RETURN:      None
1925  *
1926  * DESCRIPTION: Check entire namespace for data structure integrity
1927  *
1928  ******************************************************************************/
1929
1930 void
1931 AcpiDbCheckIntegrity (
1932     void)
1933 {
1934     ACPI_INTEGRITY_INFO     Info = {0,0};
1935
1936     /* Search all nodes in namespace */
1937
1938     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1939                     AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
1940
1941     AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1942         Info.Nodes, Info.Objects);
1943 }
1944
1945
1946 /*******************************************************************************
1947  *
1948  * FUNCTION:    AcpiDbGenerateGpe
1949  *
1950  * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1951  *              BlockArg        - GPE block number, ascii string
1952  *                                0 or 1 for FADT GPE blocks
1953  *
1954  * RETURN:      None
1955  *
1956  * DESCRIPTION: Generate a GPE
1957  *
1958  ******************************************************************************/
1959
1960 void
1961 AcpiDbGenerateGpe (
1962     char                    *GpeArg,
1963     char                    *BlockArg)
1964 {
1965     UINT32                  BlockNumber;
1966     UINT32                  GpeNumber;
1967     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1968
1969
1970     GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1971     BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1972
1973
1974     GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1975         GpeNumber);
1976     if (!GpeEventInfo)
1977     {
1978         AcpiOsPrintf ("Invalid GPE\n");
1979         return;
1980     }
1981
1982     (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1983 }
1984
1985
1986 /*******************************************************************************
1987  *
1988  * FUNCTION:    AcpiDbBusWalk
1989  *
1990  * PARAMETERS:  Callback from WalkNamespace
1991  *
1992  * RETURN:      Status
1993  *
1994  * DESCRIPTION: Display info about device objects that have a corresponding
1995  *              _PRT method.
1996  *
1997  ******************************************************************************/
1998
1999 static ACPI_STATUS
2000 AcpiDbBusWalk (
2001     ACPI_HANDLE             ObjHandle,
2002     UINT32                  NestingLevel,
2003     void                    *Context,
2004     void                    **ReturnValue)
2005 {
2006     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
2007     ACPI_STATUS             Status;
2008     ACPI_BUFFER             Buffer;
2009     ACPI_NAMESPACE_NODE     *TempNode;
2010     ACPI_DEVICE_INFO        *Info;
2011     UINT32                  i;
2012
2013
2014     if ((Node->Type != ACPI_TYPE_DEVICE) &&
2015         (Node->Type != ACPI_TYPE_PROCESSOR))
2016     {
2017         return (AE_OK);
2018     }
2019
2020     /* Exit if there is no _PRT under this device */
2021
2022     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
2023                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
2024     if (ACPI_FAILURE (Status))
2025     {
2026         return (AE_OK);
2027     }
2028
2029     /* Get the full path to this device object */
2030
2031     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
2032     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
2033     if (ACPI_FAILURE (Status))
2034     {
2035         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
2036         return (AE_OK);
2037     }
2038
2039     Status = AcpiGetObjectInfo (ObjHandle, &Info);
2040     if (ACPI_FAILURE (Status))
2041     {
2042         return (AE_OK);
2043     }
2044
2045     /* Display the full path */
2046
2047     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
2048     ACPI_FREE (Buffer.Pointer);
2049
2050     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
2051     {
2052         AcpiOsPrintf ("  - Is PCI Root Bridge");
2053     }
2054     AcpiOsPrintf ("\n");
2055
2056     /* _PRT info */
2057
2058     AcpiOsPrintf ("_PRT: %p\n", TempNode);
2059
2060     /* Dump _ADR, _HID, _UID, _CID */
2061
2062     if (Info->Valid & ACPI_VALID_ADR)
2063     {
2064         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
2065     }
2066     else
2067     {
2068         AcpiOsPrintf ("_ADR: <Not Present>\n");
2069     }
2070
2071     if (Info->Valid & ACPI_VALID_HID)
2072     {
2073         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
2074     }
2075     else
2076     {
2077         AcpiOsPrintf ("_HID: <Not Present>\n");
2078     }
2079
2080     if (Info->Valid & ACPI_VALID_UID)
2081     {
2082         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
2083     }
2084     else
2085     {
2086         AcpiOsPrintf ("_UID: <Not Present>\n");
2087     }
2088
2089     if (Info->Valid & ACPI_VALID_CID)
2090     {
2091         for (i = 0; i < Info->CompatibleIdList.Count; i++)
2092         {
2093             AcpiOsPrintf ("_CID: %s\n",
2094                 Info->CompatibleIdList.Ids[i].String);
2095         }
2096     }
2097     else
2098     {
2099         AcpiOsPrintf ("_CID: <Not Present>\n");
2100     }
2101
2102     ACPI_FREE (Info);
2103     return (AE_OK);
2104 }
2105
2106
2107 /*******************************************************************************
2108  *
2109  * FUNCTION:    AcpiDbGetBusInfo
2110  *
2111  * PARAMETERS:  None
2112  *
2113  * RETURN:      None
2114  *
2115  * DESCRIPTION: Display info about system busses.
2116  *
2117  ******************************************************************************/
2118
2119 void
2120 AcpiDbGetBusInfo (
2121     void)
2122 {
2123     /* Search all nodes in namespace */
2124
2125     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
2126                     AcpiDbBusWalk, NULL, NULL, NULL);
2127 }
2128
2129 #endif /* ACPI_DEBUGGER */