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