dbcmds.c revision 198237
1/*******************************************************************************
2 *
3 * Module Name: dbcmds - debug commands and output routines
4 *
5 ******************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights.  You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code.  No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision.  In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change.  Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee.  Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution.  In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government.  In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************/
115
116
117#include <contrib/dev/acpica/include/acpi.h>
118#include <contrib/dev/acpica/include/accommon.h>
119#include <contrib/dev/acpica/include/acdispat.h>
120#include <contrib/dev/acpica/include/acnamesp.h>
121#include <contrib/dev/acpica/include/acevents.h>
122#include <contrib/dev/acpica/include/acdebug.h>
123#include <contrib/dev/acpica/include/acresrc.h>
124#include <contrib/dev/acpica/include/acdisasm.h>
125#include <contrib/dev/acpica/include/actables.h>
126#include <contrib/dev/acpica/include/acparser.h>
127
128#ifdef ACPI_DEBUGGER
129
130#define _COMPONENT          ACPI_CA_DEBUGGER
131        ACPI_MODULE_NAME    ("dbcmds")
132
133
134/* Local prototypes */
135
136static ACPI_STATUS
137AcpiDbIntegrityWalk (
138    ACPI_HANDLE             ObjHandle,
139    UINT32                  NestingLevel,
140    void                    *Context,
141    void                    **ReturnValue);
142
143static ACPI_STATUS
144AcpiDbWalkAndMatchName (
145    ACPI_HANDLE             ObjHandle,
146    UINT32                  NestingLevel,
147    void                    *Context,
148    void                    **ReturnValue);
149
150static ACPI_STATUS
151AcpiDbWalkForReferences (
152    ACPI_HANDLE             ObjHandle,
153    UINT32                  NestingLevel,
154    void                    *Context,
155    void                    **ReturnValue);
156
157static ACPI_STATUS
158AcpiDbWalkForSpecificObjects (
159    ACPI_HANDLE             ObjHandle,
160    UINT32                  NestingLevel,
161    void                    *Context,
162    void                    **ReturnValue);
163
164static ACPI_NAMESPACE_NODE *
165AcpiDbConvertToNode (
166    char                    *InString);
167
168static void
169AcpiDmCompareAmlResources (
170    UINT8                   *Aml1Buffer,
171    ACPI_RSDESC_SIZE        Aml1BufferLength,
172    UINT8                   *Aml2Buffer,
173    ACPI_RSDESC_SIZE        Aml2BufferLength);
174
175static ACPI_STATUS
176AcpiDmTestResourceConversion (
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 */
185static 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
226static ACPI_NAMESPACE_NODE *
227AcpiDbConvertToNode (
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
283ACPI_STATUS
284AcpiDbSleep (
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
329static ACPI_STATUS
330AcpiDbWalkForReferences (
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
372void
373AcpiDbFindReferences (
374    char                    *ObjectArg)
375{
376    ACPI_OPERAND_OBJECT     *ObjDesc;
377
378
379    /* Convert string to object pointer */
380
381    ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
382
383    /* Search all nodes in namespace */
384
385    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
386                    AcpiDbWalkForReferences, (void *) ObjDesc, NULL);
387}
388
389
390/*******************************************************************************
391 *
392 * FUNCTION:    AcpiDbWalkForPredefinedNames
393 *
394 * PARAMETERS:  Callback from WalkNamespace
395 *
396 * RETURN:      Status
397 *
398 * DESCRIPTION: Detect and display predefined ACPI names (names that start with
399 *              an underscore)
400 *
401 ******************************************************************************/
402
403static ACPI_STATUS
404AcpiDbWalkForPredefinedNames (
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
468void
469AcpiDbCheckPredefinedNames (
470    void)
471{
472    UINT32                  Count = 0;
473
474
475    /* Search all nodes in namespace */
476
477    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
478                AcpiDbWalkForPredefinedNames, (void *) &Count, NULL);
479
480    AcpiOsPrintf ("Found %d predefined names in the namespace\n", Count);
481}
482
483
484/*******************************************************************************
485 *
486 * FUNCTION:    AcpiDbWalkForExecute
487 *
488 * PARAMETERS:  Callback from WalkNamespace
489 *
490 * RETURN:      Status
491 *
492 * DESCRIPTION: Batch execution module. Currently only executes predefined
493 *              ACPI names.
494 *
495 ******************************************************************************/
496
497static ACPI_STATUS
498AcpiDbWalkForExecute (
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
601void
602AcpiDbBatchExecute (
603    char                    *CountArg)
604{
605    ACPI_EXECUTE_WALK       Info;
606
607
608    Info.Count = 0;
609    Info.MaxCount = ACPI_UINT32_MAX;
610
611    if (CountArg)
612    {
613        Info.MaxCount = ACPI_STRTOUL (CountArg, NULL, 0);
614    }
615
616
617    /* Search all nodes in namespace */
618
619    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
620                AcpiDbWalkForExecute, (void *) &Info, NULL);
621
622    AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Info.Count);
623}
624
625
626/*******************************************************************************
627 *
628 * FUNCTION:    AcpiDbDisplayLocks
629 *
630 * PARAMETERS:  None
631 *
632 * RETURN:      None
633 *
634 * DESCRIPTION: Display information about internal mutexes.
635 *
636 ******************************************************************************/
637
638void
639AcpiDbDisplayLocks (
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
667void
668AcpiDbDisplayTableInfo (
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
723void
724AcpiDbUnloadAcpiTable (
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
779void
780AcpiDbSetMethodBreakpoint (
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
823void
824AcpiDbSetMethodCallBreakpoint (
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
853void
854AcpiDbDisassembleAml (
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
891ACPI_STATUS
892AcpiDbDisassembleMethod (
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
960void
961AcpiDbDumpNamespace (
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
1013void
1014AcpiDbDumpNamespaceByOwner (
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
1058void
1059AcpiDbSendNotify (
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
1113void
1114AcpiDbSetMethodData (
1115    char                    *TypeArg,
1116    char                    *IndexArg,
1117    char                    *ValueArg)
1118{
1119    char                    Type;
1120    UINT32                  Index;
1121    UINT32                  Value;
1122    ACPI_WALK_STATE         *WalkState;
1123    ACPI_OPERAND_OBJECT     *ObjDesc;
1124    ACPI_STATUS             Status;
1125    ACPI_NAMESPACE_NODE     *Node;
1126
1127
1128    /* Validate TypeArg */
1129
1130    AcpiUtStrupr (TypeArg);
1131    Type = TypeArg[0];
1132    if ((Type != 'L') &&
1133        (Type != 'A') &&
1134        (Type != 'N'))
1135    {
1136        AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
1137        return;
1138    }
1139
1140    Value = ACPI_STRTOUL (ValueArg, NULL, 16);
1141
1142    if (Type == 'N')
1143    {
1144        Node = AcpiDbConvertToNode (IndexArg);
1145        if (Node->Type != ACPI_TYPE_INTEGER)
1146        {
1147            AcpiOsPrintf ("Can only set Integer nodes\n");
1148            return;
1149        }
1150        ObjDesc = Node->Object;
1151        ObjDesc->Integer.Value = Value;
1152        return;
1153    }
1154
1155    /* Get the index and value */
1156
1157    Index = ACPI_STRTOUL (IndexArg, NULL, 16);
1158
1159    WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
1160    if (!WalkState)
1161    {
1162        AcpiOsPrintf ("There is no method currently executing\n");
1163        return;
1164    }
1165
1166    /* Create and initialize the new object */
1167
1168    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
1169    if (!ObjDesc)
1170    {
1171        AcpiOsPrintf ("Could not create an internal object\n");
1172        return;
1173    }
1174
1175    ObjDesc->Integer.Value = Value;
1176
1177    /* Store the new object into the target */
1178
1179    switch (Type)
1180    {
1181    case 'A':
1182
1183        /* Set a method argument */
1184
1185        if (Index > ACPI_METHOD_MAX_ARG)
1186        {
1187            AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
1188            goto Cleanup;
1189        }
1190
1191        Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc,
1192                    WalkState);
1193        if (ACPI_FAILURE (Status))
1194        {
1195            goto Cleanup;
1196        }
1197
1198        ObjDesc = WalkState->Arguments[Index].Object;
1199
1200        AcpiOsPrintf ("Arg%d: ", Index);
1201        AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1202        break;
1203
1204    case 'L':
1205
1206        /* Set a method local */
1207
1208        if (Index > ACPI_METHOD_MAX_LOCAL)
1209        {
1210            AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
1211            goto Cleanup;
1212        }
1213
1214        Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc,
1215                    WalkState);
1216        if (ACPI_FAILURE (Status))
1217        {
1218            goto Cleanup;
1219        }
1220
1221        ObjDesc = WalkState->LocalVariables[Index].Object;
1222
1223        AcpiOsPrintf ("Local%d: ", Index);
1224        AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1225        break;
1226
1227    default:
1228        break;
1229    }
1230
1231Cleanup:
1232    AcpiUtRemoveReference (ObjDesc);
1233}
1234
1235
1236/*******************************************************************************
1237 *
1238 * FUNCTION:    AcpiDbWalkForSpecificObjects
1239 *
1240 * PARAMETERS:  Callback from WalkNamespace
1241 *
1242 * RETURN:      Status
1243 *
1244 * DESCRIPTION: Display short info about objects in the namespace
1245 *
1246 ******************************************************************************/
1247
1248static ACPI_STATUS
1249AcpiDbWalkForSpecificObjects (
1250    ACPI_HANDLE             ObjHandle,
1251    UINT32                  NestingLevel,
1252    void                    *Context,
1253    void                    **ReturnValue)
1254{
1255    ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
1256    ACPI_BUFFER             Buffer;
1257    ACPI_STATUS             Status;
1258
1259
1260    Info->Count++;
1261
1262    /* Get and display the full pathname to this object */
1263
1264    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1265    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1266    if (ACPI_FAILURE (Status))
1267    {
1268        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1269        return (AE_OK);
1270    }
1271
1272    AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1273    ACPI_FREE (Buffer.Pointer);
1274
1275    /* Dump short info about the object */
1276
1277    (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1278    return (AE_OK);
1279}
1280
1281
1282/*******************************************************************************
1283 *
1284 * FUNCTION:    AcpiDbDisplayObjects
1285 *
1286 * PARAMETERS:  ObjTypeArg          - Type of object to display
1287 *              DisplayCountArg     - Max depth to display
1288 *
1289 * RETURN:      None
1290 *
1291 * DESCRIPTION: Display objects in the namespace of the requested type
1292 *
1293 ******************************************************************************/
1294
1295ACPI_STATUS
1296AcpiDbDisplayObjects (
1297    char                    *ObjTypeArg,
1298    char                    *DisplayCountArg)
1299{
1300    ACPI_WALK_INFO          Info;
1301    ACPI_OBJECT_TYPE        Type;
1302
1303
1304    /* Get the object type */
1305
1306    Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1307    if (Type == ACPI_TYPE_NOT_FOUND)
1308    {
1309        AcpiOsPrintf ("Invalid or unsupported argument\n");
1310        return (AE_OK);
1311    }
1312
1313    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1314    AcpiOsPrintf (
1315        "Objects of type [%s] defined in the current ACPI Namespace:\n",
1316        AcpiUtGetTypeName (Type));
1317
1318    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1319
1320    Info.Count = 0;
1321    Info.OwnerId = ACPI_OWNER_ID_MAX;
1322    Info.DebugLevel = ACPI_UINT32_MAX;
1323    Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1324
1325    /* Walk the namespace from the root */
1326
1327    (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1328                AcpiDbWalkForSpecificObjects, (void *) &Info, NULL);
1329
1330    AcpiOsPrintf (
1331        "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1332        Info.Count, AcpiUtGetTypeName (Type));
1333
1334    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1335    return (AE_OK);
1336}
1337
1338
1339/*******************************************************************************
1340 *
1341 * FUNCTION:    AcpiDbWalkAndMatchName
1342 *
1343 * PARAMETERS:  Callback from WalkNamespace
1344 *
1345 * RETURN:      Status
1346 *
1347 * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
1348 *              are supported -- '?' matches any character.
1349 *
1350 ******************************************************************************/
1351
1352static ACPI_STATUS
1353AcpiDbWalkAndMatchName (
1354    ACPI_HANDLE             ObjHandle,
1355    UINT32                  NestingLevel,
1356    void                    *Context,
1357    void                    **ReturnValue)
1358{
1359    ACPI_STATUS             Status;
1360    char                    *RequestedName = (char *) Context;
1361    UINT32                  i;
1362    ACPI_BUFFER             Buffer;
1363    ACPI_WALK_INFO          Info;
1364
1365
1366    /* Check for a name match */
1367
1368    for (i = 0; i < 4; i++)
1369    {
1370        /* Wildcard support */
1371
1372        if ((RequestedName[i] != '?') &&
1373            (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1374        {
1375            /* No match, just exit */
1376
1377            return (AE_OK);
1378        }
1379    }
1380
1381    /* Get the full pathname to this object */
1382
1383    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1384    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1385    if (ACPI_FAILURE (Status))
1386    {
1387        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1388    }
1389    else
1390    {
1391        Info.OwnerId = ACPI_OWNER_ID_MAX;
1392        Info.DebugLevel = ACPI_UINT32_MAX;
1393        Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1394
1395        AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1396        (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1397        ACPI_FREE (Buffer.Pointer);
1398    }
1399
1400    return (AE_OK);
1401}
1402
1403
1404/*******************************************************************************
1405 *
1406 * FUNCTION:    AcpiDbFindNameInNamespace
1407 *
1408 * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
1409 *                                wildcards are supported.
1410 *
1411 * RETURN:      None
1412 *
1413 * DESCRIPTION: Search the namespace for a given name (with wildcards)
1414 *
1415 ******************************************************************************/
1416
1417ACPI_STATUS
1418AcpiDbFindNameInNamespace (
1419    char                    *NameArg)
1420{
1421    char                    AcpiName[5] = "____";
1422    char                    *AcpiNamePtr = AcpiName;
1423
1424
1425    if (ACPI_STRLEN (NameArg) > 4)
1426    {
1427        AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1428        return (AE_OK);
1429    }
1430
1431    /* Pad out name with underscores as necessary to create a 4-char name */
1432
1433    AcpiUtStrupr (NameArg);
1434    while (*NameArg)
1435    {
1436        *AcpiNamePtr = *NameArg;
1437        AcpiNamePtr++;
1438        NameArg++;
1439    }
1440
1441    /* Walk the namespace from the root */
1442
1443    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1444                        AcpiDbWalkAndMatchName, AcpiName, NULL);
1445
1446    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1447    return (AE_OK);
1448}
1449
1450
1451/*******************************************************************************
1452 *
1453 * FUNCTION:    AcpiDbSetScope
1454 *
1455 * PARAMETERS:  Name                - New scope path
1456 *
1457 * RETURN:      Status
1458 *
1459 * DESCRIPTION: Set the "current scope" as maintained by this utility.
1460 *              The scope is used as a prefix to ACPI paths.
1461 *
1462 ******************************************************************************/
1463
1464void
1465AcpiDbSetScope (
1466    char                    *Name)
1467{
1468    ACPI_STATUS             Status;
1469    ACPI_NAMESPACE_NODE     *Node;
1470
1471
1472    if (!Name || Name[0] == 0)
1473    {
1474        AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1475        return;
1476    }
1477
1478    AcpiDbPrepNamestring (Name);
1479
1480    if (Name[0] == '\\')
1481    {
1482        /* Validate new scope from the root */
1483
1484        Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
1485                    &Node);
1486        if (ACPI_FAILURE (Status))
1487        {
1488            goto ErrorExit;
1489        }
1490
1491        ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1492        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1493    }
1494    else
1495    {
1496        /* Validate new scope relative to old scope */
1497
1498        Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
1499                    &Node);
1500        if (ACPI_FAILURE (Status))
1501        {
1502            goto ErrorExit;
1503        }
1504
1505        ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1506        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1507    }
1508
1509    AcpiGbl_DbScopeNode = Node;
1510    AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1511    return;
1512
1513ErrorExit:
1514
1515    AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1516        Name, AcpiFormatException (Status));
1517}
1518
1519
1520/*******************************************************************************
1521 *
1522 * FUNCTION:    AcpiDmCompareAmlResources
1523 *
1524 * PARAMETERS:  Aml1Buffer          - Contains first resource list
1525 *              Aml1BufferLength    - Length of first resource list
1526 *              Aml2Buffer          - Contains second resource list
1527 *              Aml2BufferLength    - Length of second resource list
1528 *
1529 * RETURN:      None
1530 *
1531 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1532 *              order to isolate a miscompare to an individual resource)
1533 *
1534 ******************************************************************************/
1535
1536static void
1537AcpiDmCompareAmlResources (
1538    UINT8                   *Aml1Buffer,
1539    ACPI_RSDESC_SIZE        Aml1BufferLength,
1540    UINT8                   *Aml2Buffer,
1541    ACPI_RSDESC_SIZE        Aml2BufferLength)
1542{
1543    UINT8                   *Aml1;
1544    UINT8                   *Aml2;
1545    ACPI_RSDESC_SIZE        Aml1Length;
1546    ACPI_RSDESC_SIZE        Aml2Length;
1547    ACPI_RSDESC_SIZE        Offset = 0;
1548    UINT8                   ResourceType;
1549    UINT32                  Count = 0;
1550
1551
1552    /* Compare overall buffer sizes (may be different due to size rounding) */
1553
1554    if (Aml1BufferLength != Aml2BufferLength)
1555    {
1556        AcpiOsPrintf (
1557            "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1558            Aml1BufferLength, Aml2BufferLength);
1559    }
1560
1561    Aml1 = Aml1Buffer;
1562    Aml2 = Aml2Buffer;
1563
1564    /* Walk the descriptor lists, comparing each descriptor */
1565
1566    while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1567    {
1568        /* Get the lengths of each descriptor */
1569
1570        Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1571        Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1572        ResourceType = AcpiUtGetResourceType (Aml1);
1573
1574        /* Check for descriptor length match */
1575
1576        if (Aml1Length != Aml2Length)
1577        {
1578            AcpiOsPrintf (
1579                "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1580                Count, ResourceType, Offset, Aml1Length, Aml2Length);
1581        }
1582
1583        /* Check for descriptor byte match */
1584
1585        else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1586        {
1587            AcpiOsPrintf (
1588                "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1589                Count, ResourceType, Offset);
1590        }
1591
1592        /* Exit on EndTag descriptor */
1593
1594        if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1595        {
1596            return;
1597        }
1598
1599        /* Point to next descriptor in each buffer */
1600
1601        Count++;
1602        Offset += Aml1Length;
1603        Aml1 += Aml1Length;
1604        Aml2 += Aml2Length;
1605    }
1606}
1607
1608
1609/*******************************************************************************
1610 *
1611 * FUNCTION:    AcpiDmTestResourceConversion
1612 *
1613 * PARAMETERS:  Node            - Parent device node
1614 *              Name            - resource method name (_CRS)
1615 *
1616 * RETURN:      Status
1617 *
1618 * DESCRIPTION: Compare the original AML with a conversion of the AML to
1619 *              internal resource list, then back to AML.
1620 *
1621 ******************************************************************************/
1622
1623static ACPI_STATUS
1624AcpiDmTestResourceConversion (
1625    ACPI_NAMESPACE_NODE     *Node,
1626    char                    *Name)
1627{
1628    ACPI_STATUS             Status;
1629    ACPI_BUFFER             ReturnObj;
1630    ACPI_BUFFER             ResourceObj;
1631    ACPI_BUFFER             NewAml;
1632    ACPI_OBJECT             *OriginalAml;
1633
1634
1635    AcpiOsPrintf ("Resource Conversion Comparison:\n");
1636
1637    NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1638    ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1639    ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1640
1641    /* Get the original _CRS AML resource template */
1642
1643    Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1644    if (ACPI_FAILURE (Status))
1645    {
1646        AcpiOsPrintf ("Could not obtain %s: %s\n",
1647            Name, AcpiFormatException (Status));
1648        return (Status);
1649    }
1650
1651    /* Get the AML resource template, converted to internal resource structs */
1652
1653    Status = AcpiGetCurrentResources (Node, &ResourceObj);
1654    if (ACPI_FAILURE (Status))
1655    {
1656        AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1657            AcpiFormatException (Status));
1658        goto Exit1;
1659    }
1660
1661    /* Convert internal resource list to external AML resource template */
1662
1663    Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1664    if (ACPI_FAILURE (Status))
1665    {
1666        AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1667            AcpiFormatException (Status));
1668        goto Exit2;
1669    }
1670
1671    /* Compare original AML to the newly created AML resource list */
1672
1673    OriginalAml = ReturnObj.Pointer;
1674
1675    AcpiDmCompareAmlResources (
1676        OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
1677        NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
1678
1679    /* Cleanup and exit */
1680
1681    ACPI_FREE (NewAml.Pointer);
1682Exit2:
1683    ACPI_FREE (ResourceObj.Pointer);
1684Exit1:
1685    ACPI_FREE (ReturnObj.Pointer);
1686    return (Status);
1687}
1688
1689
1690/*******************************************************************************
1691 *
1692 * FUNCTION:    AcpiDbDisplayResources
1693 *
1694 * PARAMETERS:  ObjectArg       - String with hex value of the object
1695 *
1696 * RETURN:      None
1697 *
1698 * DESCRIPTION: Display the resource objects associated with a device.
1699 *
1700 ******************************************************************************/
1701
1702void
1703AcpiDbDisplayResources (
1704    char                    *ObjectArg)
1705{
1706    ACPI_NAMESPACE_NODE     *Node;
1707    ACPI_STATUS             Status;
1708    ACPI_BUFFER             ReturnObj;
1709
1710
1711    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1712    AcpiDbgLevel |= ACPI_LV_RESOURCES;
1713
1714    /* Convert string to object pointer */
1715
1716    Node = AcpiDbConvertToNode (ObjectArg);
1717    if (!Node)
1718    {
1719        return;
1720    }
1721
1722    /* Prepare for a return object of arbitrary size */
1723
1724    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1725    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1726
1727    /* _PRT */
1728
1729    AcpiOsPrintf ("Evaluating _PRT\n");
1730
1731    /* Check if _PRT exists */
1732
1733    Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1734    if (ACPI_FAILURE (Status))
1735    {
1736        AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1737            AcpiFormatException (Status));
1738        goto GetCrs;
1739    }
1740
1741    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1742    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1743
1744    Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1745    if (ACPI_FAILURE (Status))
1746    {
1747        AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1748            AcpiFormatException (Status));
1749        goto GetCrs;
1750    }
1751
1752    AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1753
1754
1755    /* _CRS */
1756
1757GetCrs:
1758    AcpiOsPrintf ("Evaluating _CRS\n");
1759
1760    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1761    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1762
1763    /* Check if _CRS exists */
1764
1765    Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1766    if (ACPI_FAILURE (Status))
1767    {
1768        AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1769            AcpiFormatException (Status));
1770        goto GetPrs;
1771    }
1772
1773    /* Get the _CRS resource list */
1774
1775    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1776    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1777
1778    Status = AcpiGetCurrentResources (Node, &ReturnObj);
1779    if (ACPI_FAILURE (Status))
1780    {
1781        AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1782            AcpiFormatException (Status));
1783        goto GetPrs;
1784    }
1785
1786    /* Dump the _CRS resource list */
1787
1788    AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1789        ReturnObj.Pointer));
1790
1791    /*
1792     * Perform comparison of original AML to newly created AML. This tests both
1793     * the AML->Resource conversion and the Resource->Aml conversion.
1794     */
1795    Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1796
1797    /* Execute _SRS with the resource list */
1798
1799    Status = AcpiSetCurrentResources (Node, &ReturnObj);
1800    if (ACPI_FAILURE (Status))
1801    {
1802        AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1803            AcpiFormatException (Status));
1804        goto GetPrs;
1805    }
1806
1807
1808    /* _PRS */
1809
1810GetPrs:
1811    AcpiOsPrintf ("Evaluating _PRS\n");
1812
1813    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1814    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1815
1816    /* Check if _PRS exists */
1817
1818    Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1819    if (ACPI_FAILURE (Status))
1820    {
1821        AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1822            AcpiFormatException (Status));
1823        goto Cleanup;
1824    }
1825
1826    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1827    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1828
1829    Status = AcpiGetPossibleResources (Node, &ReturnObj);
1830    if (ACPI_FAILURE (Status))
1831    {
1832        AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1833            AcpiFormatException (Status));
1834        goto Cleanup;
1835    }
1836
1837    AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1838
1839Cleanup:
1840
1841    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1842    return;
1843}
1844
1845
1846/*******************************************************************************
1847 *
1848 * FUNCTION:    AcpiDbIntegrityWalk
1849 *
1850 * PARAMETERS:  Callback from WalkNamespace
1851 *
1852 * RETURN:      Status
1853 *
1854 * DESCRIPTION: Examine one NS node for valid values.
1855 *
1856 ******************************************************************************/
1857
1858static ACPI_STATUS
1859AcpiDbIntegrityWalk (
1860    ACPI_HANDLE             ObjHandle,
1861    UINT32                  NestingLevel,
1862    void                    *Context,
1863    void                    **ReturnValue)
1864{
1865    ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1866    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1867    ACPI_OPERAND_OBJECT     *Object;
1868    BOOLEAN                 Alias = TRUE;
1869
1870
1871    Info->Nodes++;
1872
1873    /* Verify the NS node, and dereference aliases */
1874
1875    while (Alias)
1876    {
1877        if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1878        {
1879            AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
1880                Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
1881                ACPI_DESC_TYPE_NAMED);
1882            return (AE_OK);
1883        }
1884
1885        if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
1886            (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
1887        {
1888            Node = (ACPI_NAMESPACE_NODE *) Node->Object;
1889        }
1890        else
1891        {
1892            Alias = FALSE;
1893        }
1894    }
1895
1896    if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1897    {
1898        AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1899            Node, Node->Type);
1900        return (AE_OK);
1901    }
1902
1903    if (!AcpiUtValidAcpiName (Node->Name.Integer))
1904    {
1905        AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1906        return (AE_OK);
1907    }
1908
1909    Object = AcpiNsGetAttachedObject (Node);
1910    if (Object)
1911    {
1912        Info->Objects++;
1913        if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1914        {
1915            AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1916                Object, AcpiUtGetDescriptorName (Object));
1917        }
1918    }
1919
1920    return (AE_OK);
1921}
1922
1923
1924/*******************************************************************************
1925 *
1926 * FUNCTION:    AcpiDbCheckIntegrity
1927 *
1928 * PARAMETERS:  None
1929 *
1930 * RETURN:      None
1931 *
1932 * DESCRIPTION: Check entire namespace for data structure integrity
1933 *
1934 ******************************************************************************/
1935
1936void
1937AcpiDbCheckIntegrity (
1938    void)
1939{
1940    ACPI_INTEGRITY_INFO     Info = {0,0};
1941
1942    /* Search all nodes in namespace */
1943
1944    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1945                    AcpiDbIntegrityWalk, (void *) &Info, NULL);
1946
1947    AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1948        Info.Nodes, Info.Objects);
1949}
1950
1951
1952/*******************************************************************************
1953 *
1954 * FUNCTION:    AcpiDbGenerateGpe
1955 *
1956 * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1957 *              BlockArg        - GPE block number, ascii string
1958 *                                0 or 1 for FADT GPE blocks
1959 *
1960 * RETURN:      None
1961 *
1962 * DESCRIPTION: Generate a GPE
1963 *
1964 ******************************************************************************/
1965
1966void
1967AcpiDbGenerateGpe (
1968    char                    *GpeArg,
1969    char                    *BlockArg)
1970{
1971    UINT32                  BlockNumber;
1972    UINT32                  GpeNumber;
1973    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1974
1975
1976    GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1977    BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1978
1979
1980    GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1981        GpeNumber);
1982    if (!GpeEventInfo)
1983    {
1984        AcpiOsPrintf ("Invalid GPE\n");
1985        return;
1986    }
1987
1988    (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1989}
1990
1991
1992/*******************************************************************************
1993 *
1994 * FUNCTION:    AcpiDbBusWalk
1995 *
1996 * PARAMETERS:  Callback from WalkNamespace
1997 *
1998 * RETURN:      Status
1999 *
2000 * DESCRIPTION: Display info about device objects that have a corresponding
2001 *              _PRT method.
2002 *
2003 ******************************************************************************/
2004
2005static ACPI_STATUS
2006AcpiDbBusWalk (
2007    ACPI_HANDLE             ObjHandle,
2008    UINT32                  NestingLevel,
2009    void                    *Context,
2010    void                    **ReturnValue)
2011{
2012    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
2013    ACPI_STATUS             Status;
2014    ACPI_BUFFER             Buffer;
2015    ACPI_NAMESPACE_NODE     *TempNode;
2016    ACPI_DEVICE_INFO        *Info;
2017    UINT32                  i;
2018
2019
2020    if ((Node->Type != ACPI_TYPE_DEVICE) &&
2021        (Node->Type != ACPI_TYPE_PROCESSOR))
2022    {
2023        return (AE_OK);
2024    }
2025
2026    /* Exit if there is no _PRT under this device */
2027
2028    Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
2029                ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
2030    if (ACPI_FAILURE (Status))
2031    {
2032        return (AE_OK);
2033    }
2034
2035    /* Get the full path to this device object */
2036
2037    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
2038    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
2039    if (ACPI_FAILURE (Status))
2040    {
2041        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
2042        return (AE_OK);
2043    }
2044
2045    Status = AcpiGetObjectInfo (ObjHandle, &Info);
2046    if (ACPI_FAILURE (Status))
2047    {
2048        return (AE_OK);
2049    }
2050
2051    /* Display the full path */
2052
2053    AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
2054    ACPI_FREE (Buffer.Pointer);
2055
2056    if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
2057    {
2058        AcpiOsPrintf ("  - Is PCI Root Bridge");
2059    }
2060    AcpiOsPrintf ("\n");
2061
2062    /* _PRT info */
2063
2064    AcpiOsPrintf ("_PRT: %p\n", TempNode);
2065
2066    /* Dump _ADR, _HID, _UID, _CID */
2067
2068    if (Info->Valid & ACPI_VALID_ADR)
2069    {
2070        AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
2071    }
2072    else
2073    {
2074        AcpiOsPrintf ("_ADR: <Not Present>\n");
2075    }
2076
2077    if (Info->Valid & ACPI_VALID_HID)
2078    {
2079        AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
2080    }
2081    else
2082    {
2083        AcpiOsPrintf ("_HID: <Not Present>\n");
2084    }
2085
2086    if (Info->Valid & ACPI_VALID_UID)
2087    {
2088        AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
2089    }
2090    else
2091    {
2092        AcpiOsPrintf ("_UID: <Not Present>\n");
2093    }
2094
2095    if (Info->Valid & ACPI_VALID_CID)
2096    {
2097        for (i = 0; i < Info->CompatibleIdList.Count; i++)
2098        {
2099            AcpiOsPrintf ("_CID: %s\n",
2100                Info->CompatibleIdList.Ids[i].String);
2101        }
2102    }
2103    else
2104    {
2105        AcpiOsPrintf ("_CID: <Not Present>\n");
2106    }
2107
2108    ACPI_FREE (Info);
2109    return (AE_OK);
2110}
2111
2112
2113/*******************************************************************************
2114 *
2115 * FUNCTION:    AcpiDbGetBusInfo
2116 *
2117 * PARAMETERS:  None
2118 *
2119 * RETURN:      None
2120 *
2121 * DESCRIPTION: Display info about system busses.
2122 *
2123 ******************************************************************************/
2124
2125void
2126AcpiDbGetBusInfo (
2127    void)
2128{
2129    /* Search all nodes in namespace */
2130
2131    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
2132                    AcpiDbBusWalk, NULL, NULL);
2133}
2134
2135#endif /* ACPI_DEBUGGER */
2136