dbcmds.c revision 193251
1234353Sdim/*******************************************************************************
2234353Sdim *
3218885Sdim * Module Name: dbcmds - debug commands and output routines
4218885Sdim *              $Revision: 1.150 $
5218885Sdim *
6218885Sdim ******************************************************************************/
7234353Sdim
8218885Sdim/******************************************************************************
9218885Sdim *
10218885Sdim * 1. Copyright Notice
11218885Sdim *
12218885Sdim * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
13218885Sdim * All rights reserved.
14218885Sdim *
15218885Sdim * 2. License
16218885Sdim *
17218885Sdim * 2.1. This is your license from Intel Corp. under its intellectual property
18218885Sdim * rights.  You may have additional license terms from the party that provided
19226633Sdim * you this software, covering your right to use that party's intellectual
20239462Sdim * property rights.
21234353Sdim *
22226633Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23239462Sdim * copy of the source code appearing in this file ("Covered Code") an
24234353Sdim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25218885Sdim * base code distributed originally by Intel ("Original Intel Code") to copy,
26226633Sdim * make derivatives, distribute, use and display any portion of the Covered
27239462Sdim * Code in any form, with the right to sublicense such rights; and
28234353Sdim *
29226633Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30239462Sdim * license (with the right to sublicense), under only those claims of Intel
31234353Sdim * patents that are infringed by the Original Intel Code, to make, use, sell,
32218885Sdim * offer to sell, and import the Covered Code and derivative works thereof
33218885Sdim * solely to the minimum extent necessary to exercise the above copyright
34218885Sdim * license, and in no event shall the patent license extend to any additions
35218885Sdim * to or modifications of the Original Intel Code.  No other license or right
36234353Sdim * is granted directly or by implication, estoppel or otherwise;
37234353Sdim *
38218885Sdim * The above copyright and patent license is granted only if the following
39218885Sdim * conditions are met:
40218885Sdim *
41218885Sdim * 3. Conditions
42218885Sdim *
43218885Sdim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44218885Sdim * Redistribution of source code of any substantial portion of the Covered
45218885Sdim * Code or modification with rights to further distribute source must include
46218885Sdim * the above Copyright Notice, the above License, this list of Conditions,
47234353Sdim * and the following Disclaimer and Export Compliance provision.  In addition,
48218885Sdim * Licensee must cause all Covered Code to which Licensee contributes to
49234353Sdim * contain a file documenting the changes Licensee made to create that Covered
50218885Sdim * Code and the date of any change.  Licensee must include in that file the
51234353Sdim * documentation of any changes made by any predecessor Licensee.  Licensee
52218885Sdim * must include a prominent statement that the modification is derived,
53234353Sdim * directly or indirectly, from Original Intel Code.
54218885Sdim *
55234353Sdim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56218885Sdim * Redistribution of source code of any substantial portion of the Covered
57234353Sdim * Code or modification without rights to further distribute source must
58218885Sdim * include the following Disclaimer and Export Compliance provision in the
59234353Sdim * documentation and/or other materials provided with distribution.  In
60218885Sdim * addition, Licensee may not authorize further sublicense of source of any
61234353Sdim * portion of the Covered Code, and must include terms to the effect that the
62218885Sdim * license from Licensee to its licensee is limited to the intellectual
63218885Sdim * property embodied in the software Licensee provides to its licensee, and
64218885Sdim * not to intellectual property embodied in modifications its licensee may
65234353Sdim * make.
66218885Sdim *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#include "acpi.h"
119#include "acdispat.h"
120#include "amlcode.h"
121#include "acnamesp.h"
122#include "acevents.h"
123#include "acdebug.h"
124#include "acresrc.h"
125#include "acdisasm.h"
126
127
128#include "acparser.h"
129
130#ifdef ACPI_DEBUGGER
131
132#define _COMPONENT          ACPI_CA_DEBUGGER
133        ACPI_MODULE_NAME    ("dbcmds")
134
135/* Local prototypes */
136
137static ACPI_STATUS
138AcpiDbIntegrityWalk (
139    ACPI_HANDLE             ObjHandle,
140    UINT32                  NestingLevel,
141    void                    *Context,
142    void                    **ReturnValue);
143
144static ACPI_STATUS
145AcpiDbWalkAndMatchName (
146    ACPI_HANDLE             ObjHandle,
147    UINT32                  NestingLevel,
148    void                    *Context,
149    void                    **ReturnValue);
150
151static ACPI_STATUS
152AcpiDbWalkForReferences (
153    ACPI_HANDLE             ObjHandle,
154    UINT32                  NestingLevel,
155    void                    *Context,
156    void                    **ReturnValue);
157
158static ACPI_STATUS
159AcpiDbWalkForSpecificObjects (
160    ACPI_HANDLE             ObjHandle,
161    UINT32                  NestingLevel,
162    void                    *Context,
163    void                    **ReturnValue);
164
165static ACPI_NAMESPACE_NODE *
166AcpiDbConvertToNode (
167    char                    *InString);
168
169static void
170AcpiDmCompareAmlResources (
171    UINT8                   *Aml1Buffer,
172    ACPI_RSDESC_SIZE        Aml1BufferLength,
173    UINT8                   *Aml2Buffer,
174    ACPI_RSDESC_SIZE        Aml2BufferLength);
175
176static ACPI_STATUS
177AcpiDmTestResourceConversion (
178    ACPI_NAMESPACE_NODE     *Node,
179    char                    *Name);
180
181
182/*
183 * Arguments for the Objects command
184 * These object types map directly to the ACPI_TYPES
185 */
186static ARGUMENT_INFO        AcpiDbObjectTypes [] =
187{
188    {"ANY"},
189    {"INTEGERS"},
190    {"STRINGS"},
191    {"BUFFERS"},
192    {"PACKAGES"},
193    {"FIELDS"},
194    {"DEVICES"},
195    {"EVENTS"},
196    {"METHODS"},
197    {"MUTEXES"},
198    {"REGIONS"},
199    {"POWERRESOURCES"},
200    {"PROCESSORS"},
201    {"THERMALZONES"},
202    {"BUFFERFIELDS"},
203    {"DDBHANDLES"},
204    {"DEBUG"},
205    {"REGIONFIELDS"},
206    {"BANKFIELDS"},
207    {"INDEXFIELDS"},
208    {"REFERENCES"},
209    {"ALIAS"},
210    {NULL}           /* Must be null terminated */
211};
212
213
214/*******************************************************************************
215 *
216 * FUNCTION:    AcpiDbConvertToNode
217 *
218 * PARAMETERS:  InString        - String to convert
219 *
220 * RETURN:      Pointer to a NS node
221 *
222 * DESCRIPTION: Convert a string to a valid NS pointer.  Handles numeric or
223 *              alpha strings.
224 *
225 ******************************************************************************/
226
227static ACPI_NAMESPACE_NODE *
228AcpiDbConvertToNode (
229    char                    *InString)
230{
231    ACPI_NAMESPACE_NODE     *Node;
232
233
234    if ((*InString >= 0x30) && (*InString <= 0x39))
235    {
236        /* Numeric argument, convert */
237
238        Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
239        if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
240        {
241            AcpiOsPrintf ("Address %p is invalid in this address space\n",
242                Node);
243            return (NULL);
244        }
245
246        /* Make sure pointer is valid NS node */
247
248        if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
249        {
250            AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
251                    Node, AcpiUtGetDescriptorName (Node));
252            return (NULL);
253        }
254    }
255    else
256    {
257        /* Alpha argument */
258        /* The parameter is a name string that must be resolved to a
259         * Named obj
260         */
261        Node = AcpiDbLocalNsLookup (InString);
262        if (!Node)
263        {
264            Node = AcpiGbl_RootNode;
265        }
266    }
267
268    return (Node);
269}
270
271
272/*******************************************************************************
273 *
274 * FUNCTION:    AcpiDbSleep
275 *
276 * PARAMETERS:  ObjectArg       - Desired sleep state (0-5)
277 *
278 * RETURN:      Status
279 *
280 * DESCRIPTION: Simulate a sleep/wake sequence
281 *
282 ******************************************************************************/
283
284ACPI_STATUS
285AcpiDbSleep (
286    char                    *ObjectArg)
287{
288    ACPI_STATUS             Status;
289    UINT8                   SleepState;
290
291
292    SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
293
294    AcpiOsPrintf ("**** Prepare to sleep ****\n");
295    Status = AcpiEnterSleepStatePrep (SleepState);
296    if (ACPI_FAILURE (Status))
297    {
298        return (Status);
299    }
300
301    AcpiOsPrintf ("**** Going to sleep ****\n");
302    Status = AcpiEnterSleepState (SleepState);
303    if (ACPI_FAILURE (Status))
304    {
305        return (Status);
306    }
307
308    AcpiOsPrintf ("**** returning from sleep ****\n");
309    Status = AcpiLeaveSleepState (SleepState);
310
311    return (Status);
312}
313
314
315/*******************************************************************************
316 *
317 * FUNCTION:    AcpiDbWalkForReferences
318 *
319 * PARAMETERS:  Callback from WalkNamespace
320 *
321 * RETURN:      Status
322 *
323 * DESCRIPTION: Check if this namespace object refers to the target object
324 *              that is passed in as the context value.
325 *
326 * Note: Currently doesn't check subobjects within the Node's object
327 *
328 ******************************************************************************/
329
330static ACPI_STATUS
331AcpiDbWalkForReferences (
332    ACPI_HANDLE             ObjHandle,
333    UINT32                  NestingLevel,
334    void                    *Context,
335    void                    **ReturnValue)
336{
337    ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
338    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
339
340
341    /* Check for match against the namespace node itself */
342
343    if (Node == (void *) ObjDesc)
344    {
345        AcpiOsPrintf ("Object is a Node [%4.4s]\n",
346            AcpiUtGetNodeName (Node));
347    }
348
349    /* Check for match against the object attached to the node */
350
351    if (AcpiNsGetAttachedObject (Node) == ObjDesc)
352    {
353        AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
354            Node, AcpiUtGetNodeName (Node));
355    }
356
357    return (AE_OK);
358}
359
360
361/*******************************************************************************
362 *
363 * FUNCTION:    AcpiDbFindReferences
364 *
365 * PARAMETERS:  ObjectArg       - String with hex value of the object
366 *
367 * RETURN:      None
368 *
369 * DESCRIPTION: Search namespace for all references to the input object
370 *
371 ******************************************************************************/
372
373void
374AcpiDbFindReferences (
375    char                    *ObjectArg)
376{
377    ACPI_OPERAND_OBJECT     *ObjDesc;
378
379
380    /* Convert string to object pointer */
381
382    ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
383
384    /* Search all nodes in namespace */
385
386    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
387                    AcpiDbWalkForReferences, (void *) ObjDesc, NULL);
388}
389
390
391/*******************************************************************************
392 *
393 * FUNCTION:    AcpiDbDisplayLocks
394 *
395 * PARAMETERS:  None
396 *
397 * RETURN:      None
398 *
399 * DESCRIPTION: Display information about internal mutexes.
400 *
401 ******************************************************************************/
402
403void
404AcpiDbDisplayLocks (
405    void)
406{
407    UINT32                  i;
408
409
410    for (i = 0; i < ACPI_MAX_MUTEX; i++)
411    {
412        AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
413            AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
414                ? "Locked" : "Unlocked");
415    }
416}
417
418
419/*******************************************************************************
420 *
421 * FUNCTION:    AcpiDbDisplayTableInfo
422 *
423 * PARAMETERS:  TableArg        - String with name of table to be displayed
424 *
425 * RETURN:      None
426 *
427 * DESCRIPTION: Display information about loaded tables.  Current
428 *              implementation displays all loaded tables.
429 *
430 ******************************************************************************/
431
432void
433AcpiDbDisplayTableInfo (
434    char                    *TableArg)
435{
436    ACPI_NATIVE_UINT        i;
437    ACPI_TABLE_DESC         *TableDesc;
438
439
440    /*
441     * Walk the root table list
442     */
443    for (i = 0; i < AcpiGbl_RootTableList.Count; i++)
444    {
445        TableDesc = &AcpiGbl_RootTableList.Tables[i];
446        AcpiOsPrintf ( "%4.4s at %p length %.5X",
447                TableDesc->Signature.Ascii, TableDesc->Pointer,
448                (UINT32) TableDesc->Length);
449
450        if (TableDesc->Pointer && (i != ACPI_TABLE_INDEX_FACS))
451        {
452            AcpiOsPrintf (" OemId=\"%6s\" OemTableId=\"%8s\" OemRevision=%8.8X",
453                    TableDesc->Pointer->OemId,
454                    TableDesc->Pointer->OemTableId,
455                    TableDesc->Pointer->OemRevision);
456        }
457        AcpiOsPrintf ("\n");
458    }
459}
460
461
462/*******************************************************************************
463 *
464 * FUNCTION:    AcpiDbUnloadAcpiTable
465 *
466 * PARAMETERS:  TableArg        - Name of the table to be unloaded
467 *              InstanceArg     - Which instance of the table to unload (if
468 *                                there are multiple tables of the same type)
469 *
470 * RETURN:      Nonde
471 *
472 * DESCRIPTION: Unload an ACPI table.
473 *              Instance is not implemented
474 *
475 ******************************************************************************/
476
477void
478AcpiDbUnloadAcpiTable (
479    char                    *TableArg,
480    char                    *InstanceArg)
481{
482/* TBD: Need to reimplement for new data structures */
483
484#if 0
485    UINT32                  i;
486    ACPI_STATUS             Status;
487
488
489    /* Search all tables for the target type */
490
491    for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
492    {
493        if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
494                AcpiGbl_TableData[i].SigLength))
495        {
496            /* Found the table, unload it */
497
498            Status = AcpiUnloadTable (i);
499            if (ACPI_SUCCESS (Status))
500            {
501                AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
502            }
503            else
504            {
505                AcpiOsPrintf ("%s, while unloading [%s]\n",
506                    AcpiFormatException (Status), TableArg);
507            }
508
509            return;
510        }
511    }
512
513    AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
514#endif
515}
516
517
518/*******************************************************************************
519 *
520 * FUNCTION:    AcpiDbSetMethodBreakpoint
521 *
522 * PARAMETERS:  Location            - AML offset of breakpoint
523 *              WalkState           - Current walk info
524 *              Op                  - Current Op (from parse walk)
525 *
526 * RETURN:      None
527 *
528 * DESCRIPTION: Set a breakpoint in a control method at the specified
529 *              AML offset
530 *
531 ******************************************************************************/
532
533void
534AcpiDbSetMethodBreakpoint (
535    char                    *Location,
536    ACPI_WALK_STATE         *WalkState,
537    ACPI_PARSE_OBJECT       *Op)
538{
539    UINT32                  Address;
540
541
542    if (!Op)
543    {
544        AcpiOsPrintf ("There is no method currently executing\n");
545        return;
546    }
547
548    /* Get and verify the breakpoint address */
549
550    Address = ACPI_STRTOUL (Location, NULL, 16);
551    if (Address <= Op->Common.AmlOffset)
552    {
553        AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
554            Address, Op->Common.AmlOffset);
555    }
556
557    /* Save breakpoint in current walk */
558
559    WalkState->UserBreakpoint = Address;
560    AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
561}
562
563
564/*******************************************************************************
565 *
566 * FUNCTION:    AcpiDbSetMethodCallBreakpoint
567 *
568 * PARAMETERS:  Op                  - Current Op (from parse walk)
569 *
570 * RETURN:      None
571 *
572 * DESCRIPTION: Set a breakpoint in a control method at the specified
573 *              AML offset
574 *
575 ******************************************************************************/
576
577void
578AcpiDbSetMethodCallBreakpoint (
579    ACPI_PARSE_OBJECT       *Op)
580{
581
582
583    if (!Op)
584    {
585        AcpiOsPrintf ("There is no method currently executing\n");
586        return;
587    }
588
589    AcpiGbl_StepToNextCall = TRUE;
590}
591
592
593/*******************************************************************************
594 *
595 * FUNCTION:    AcpiDbDisassembleAml
596 *
597 * PARAMETERS:  Statements          - Number of statements to disassemble
598 *              Op                  - Current Op (from parse walk)
599 *
600 * RETURN:      None
601 *
602 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
603 *              of statements specified.
604 *
605 ******************************************************************************/
606
607void
608AcpiDbDisassembleAml (
609    char                    *Statements,
610    ACPI_PARSE_OBJECT       *Op)
611{
612    UINT32                  NumStatements = 8;
613
614
615    if (!Op)
616    {
617        AcpiOsPrintf ("There is no method currently executing\n");
618        return;
619    }
620
621    if (Statements)
622    {
623        NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
624    }
625
626    AcpiDmDisassemble (NULL, Op, NumStatements);
627}
628
629
630/*******************************************************************************
631 *
632 * FUNCTION:    AcpiDbDisassembleMethod
633 *
634 * PARAMETERS:  Name            - Name of control method
635 *
636 * RETURN:      None
637 *
638 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
639 *              of statements specified.
640 *
641 ******************************************************************************/
642
643ACPI_STATUS
644AcpiDbDisassembleMethod (
645    char                    *Name)
646{
647    ACPI_STATUS             Status;
648    ACPI_PARSE_OBJECT       *Op;
649    ACPI_WALK_STATE         *WalkState;
650    ACPI_OPERAND_OBJECT     *ObjDesc;
651    ACPI_NAMESPACE_NODE     *Method;
652
653
654    Method = AcpiDbConvertToNode (Name);
655    if (!Method)
656    {
657        return (AE_BAD_PARAMETER);
658    }
659
660    ObjDesc = Method->Object;
661
662    Op = AcpiPsCreateScopeOp ();
663    if (!Op)
664    {
665        return (AE_NO_MEMORY);
666    }
667
668    /* Create and initialize a new walk state */
669
670    WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
671    if (!WalkState)
672    {
673        return (AE_NO_MEMORY);
674    }
675
676    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
677                    ObjDesc->Method.AmlStart,
678                    ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
679    if (ACPI_FAILURE (Status))
680    {
681        return (Status);
682    }
683
684    /* Parse the AML */
685
686    WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
687    WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
688    Status = AcpiPsParseAml (WalkState);
689
690    AcpiDmDisassemble (NULL, Op, 0);
691    AcpiPsDeleteParseTree (Op);
692    return (AE_OK);
693}
694
695
696/*******************************************************************************
697 *
698 * FUNCTION:    AcpiDbDumpNamespace
699 *
700 * PARAMETERS:  StartArg        - Node to begin namespace dump
701 *              DepthArg        - Maximum tree depth to be dumped
702 *
703 * RETURN:      None
704 *
705 * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
706 *              with type and other information.
707 *
708 ******************************************************************************/
709
710void
711AcpiDbDumpNamespace (
712    char                    *StartArg,
713    char                    *DepthArg)
714{
715    ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
716    UINT32                  MaxDepth = ACPI_UINT32_MAX;
717
718
719    /* No argument given, just start at the root and dump entire namespace */
720
721    if (StartArg)
722    {
723        SubtreeEntry = AcpiDbConvertToNode (StartArg);
724        if (!SubtreeEntry)
725        {
726            return;
727        }
728
729        /* Now we can check for the depth argument */
730
731        if (DepthArg)
732        {
733            MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
734        }
735    }
736
737    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
738    AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
739        ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
740
741    /* Display the subtree */
742
743    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
744    AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
745        ACPI_OWNER_ID_MAX, SubtreeEntry);
746    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
747}
748
749
750/*******************************************************************************
751 *
752 * FUNCTION:    AcpiDbDumpNamespaceByOwner
753 *
754 * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
755 *              DepthArg        - Maximum tree depth to be dumped
756 *
757 * RETURN:      None
758 *
759 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
760 *
761 ******************************************************************************/
762
763void
764AcpiDbDumpNamespaceByOwner (
765    char                    *OwnerArg,
766    char                    *DepthArg)
767{
768    ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
769    UINT32                  MaxDepth = ACPI_UINT32_MAX;
770    ACPI_OWNER_ID           OwnerId;
771
772
773    OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
774
775    /* Now we can check for the depth argument */
776
777    if (DepthArg)
778    {
779        MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
780    }
781
782    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
783    AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
784
785    /* Display the subtree */
786
787    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
788    AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
789        SubtreeEntry);
790    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
791}
792
793
794/*******************************************************************************
795 *
796 * FUNCTION:    AcpiDbSendNotify
797 *
798 * PARAMETERS:  Name            - Name of ACPI object to send the notify to
799 *              Value           - Value of the notify to send.
800 *
801 * RETURN:      None
802 *
803 * DESCRIPTION: Send an ACPI notification.  The value specified is sent to the
804 *              named object as an ACPI notify.
805 *
806 ******************************************************************************/
807
808void
809AcpiDbSendNotify (
810    char                    *Name,
811    UINT32                  Value)
812{
813    ACPI_NAMESPACE_NODE     *Node;
814    ACPI_STATUS             Status;
815
816
817    /* Translate name to an Named object */
818
819    Node = AcpiDbConvertToNode (Name);
820    if (!Node)
821    {
822        return;
823    }
824
825    /* Decode Named object type */
826
827    switch (Node->Type)
828    {
829    case ACPI_TYPE_DEVICE:
830    case ACPI_TYPE_THERMAL:
831
832         /* Send the notify */
833
834        Status = AcpiEvQueueNotifyRequest (Node, Value);
835        if (ACPI_FAILURE (Status))
836        {
837            AcpiOsPrintf ("Could not queue notify\n");
838        }
839        break;
840
841    default:
842        AcpiOsPrintf ("Named object is not a device or a thermal object\n");
843        break;
844    }
845}
846
847
848/*******************************************************************************
849 *
850 * FUNCTION:    AcpiDbSetMethodData
851 *
852 * PARAMETERS:  TypeArg         - L for local, A for argument
853 *              IndexArg        - which one
854 *              ValueArg        - Value to set.
855 *
856 * RETURN:      None
857 *
858 * DESCRIPTION: Set a local or argument for the running control method.
859 *              NOTE: only object supported is Number.
860 *
861 ******************************************************************************/
862
863void
864AcpiDbSetMethodData (
865    char                    *TypeArg,
866    char                    *IndexArg,
867    char                    *ValueArg)
868{
869    char                    Type;
870    UINT32                  Index;
871    UINT32                  Value;
872    ACPI_WALK_STATE         *WalkState;
873    ACPI_OPERAND_OBJECT     *ObjDesc;
874    ACPI_STATUS             Status;
875    ACPI_NAMESPACE_NODE     *Node;
876
877
878    /* Validate TypeArg */
879
880    AcpiUtStrupr (TypeArg);
881    Type = TypeArg[0];
882    if ((Type != 'L') &&
883        (Type != 'A') &&
884        (Type != 'N'))
885    {
886        AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
887        return;
888    }
889
890    Value = ACPI_STRTOUL (ValueArg, NULL, 16);
891
892    if (Type == 'N')
893    {
894        Node = AcpiDbConvertToNode (IndexArg);
895        if (Node->Type != ACPI_TYPE_INTEGER)
896        {
897            AcpiOsPrintf ("Can only set Integer nodes\n");
898            return;
899        }
900        ObjDesc = Node->Object;
901        ObjDesc->Integer.Value = Value;
902        return;
903    }
904
905    /* Get the index and value */
906
907    Index = ACPI_STRTOUL (IndexArg, NULL, 16);
908
909    WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
910    if (!WalkState)
911    {
912        AcpiOsPrintf ("There is no method currently executing\n");
913        return;
914    }
915
916    /* Create and initialize the new object */
917
918    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
919    if (!ObjDesc)
920    {
921        AcpiOsPrintf ("Could not create an internal object\n");
922        return;
923    }
924
925    ObjDesc->Integer.Value = Value;
926
927    /* Store the new object into the target */
928
929    switch (Type)
930    {
931    case 'A':
932
933        /* Set a method argument */
934
935        if (Index > ACPI_METHOD_MAX_ARG)
936        {
937            AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
938            goto Cleanup;
939        }
940
941        Status = AcpiDsStoreObjectToLocal (AML_ARG_OP, Index, ObjDesc,
942                    WalkState);
943        if (ACPI_FAILURE (Status))
944        {
945            goto Cleanup;
946        }
947
948        ObjDesc = WalkState->Arguments[Index].Object;
949
950        AcpiOsPrintf ("Arg%d: ", Index);
951        AcpiDmDisplayInternalObject (ObjDesc, WalkState);
952        break;
953
954    case 'L':
955
956        /* Set a method local */
957
958        if (Index > ACPI_METHOD_MAX_LOCAL)
959        {
960            AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
961            goto Cleanup;
962        }
963
964        Status = AcpiDsStoreObjectToLocal (AML_LOCAL_OP, Index, ObjDesc,
965                    WalkState);
966        if (ACPI_FAILURE (Status))
967        {
968            goto Cleanup;
969        }
970
971        ObjDesc = WalkState->LocalVariables[Index].Object;
972
973        AcpiOsPrintf ("Local%d: ", Index);
974        AcpiDmDisplayInternalObject (ObjDesc, WalkState);
975        break;
976
977    default:
978        break;
979    }
980
981Cleanup:
982    AcpiUtRemoveReference (ObjDesc);
983}
984
985
986/*******************************************************************************
987 *
988 * FUNCTION:    AcpiDbWalkForSpecificObjects
989 *
990 * PARAMETERS:  Callback from WalkNamespace
991 *
992 * RETURN:      Status
993 *
994 * DESCRIPTION: Display short info about objects in the namespace
995 *
996 ******************************************************************************/
997
998static ACPI_STATUS
999AcpiDbWalkForSpecificObjects (
1000    ACPI_HANDLE             ObjHandle,
1001    UINT32                  NestingLevel,
1002    void                    *Context,
1003    void                    **ReturnValue)
1004{
1005    ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
1006    ACPI_BUFFER             Buffer;
1007    ACPI_STATUS             Status;
1008
1009
1010    Info->Count++;
1011
1012    /* Get and display the full pathname to this object */
1013
1014    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1015    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1016    if (ACPI_FAILURE (Status))
1017    {
1018        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1019        return (AE_OK);
1020    }
1021
1022    AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1023    ACPI_FREE (Buffer.Pointer);
1024
1025    /* Dump short info about the object */
1026
1027    (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1028    return (AE_OK);
1029}
1030
1031
1032/*******************************************************************************
1033 *
1034 * FUNCTION:    AcpiDbDisplayObjects
1035 *
1036 * PARAMETERS:  ObjTypeArg          - Type of object to display
1037 *              DisplayCountArg     - Max depth to display
1038 *
1039 * RETURN:      None
1040 *
1041 * DESCRIPTION: Display objects in the namespace of the requested type
1042 *
1043 ******************************************************************************/
1044
1045ACPI_STATUS
1046AcpiDbDisplayObjects (
1047    char                    *ObjTypeArg,
1048    char                    *DisplayCountArg)
1049{
1050    ACPI_WALK_INFO          Info;
1051    ACPI_OBJECT_TYPE        Type;
1052
1053
1054    /* Get the object type */
1055
1056    Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1057    if (Type == ACPI_TYPE_NOT_FOUND)
1058    {
1059        AcpiOsPrintf ("Invalid or unsupported argument\n");
1060        return (AE_OK);
1061    }
1062
1063    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1064    AcpiOsPrintf (
1065        "Objects of type [%s] defined in the current ACPI Namespace:\n",
1066        AcpiUtGetTypeName (Type));
1067
1068    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1069
1070    Info.Count = 0;
1071    Info.OwnerId = ACPI_OWNER_ID_MAX;
1072    Info.DebugLevel = ACPI_UINT32_MAX;
1073    Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1074
1075    /* Walk the namespace from the root */
1076
1077    (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1078                AcpiDbWalkForSpecificObjects, (void *) &Info, NULL);
1079
1080    AcpiOsPrintf (
1081        "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1082        Info.Count, AcpiUtGetTypeName (Type));
1083
1084    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1085    return (AE_OK);
1086}
1087
1088
1089/*******************************************************************************
1090 *
1091 * FUNCTION:    AcpiDbWalkAndMatchName
1092 *
1093 * PARAMETERS:  Callback from WalkNamespace
1094 *
1095 * RETURN:      Status
1096 *
1097 * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
1098 *              are supported -- '?' matches any character.
1099 *
1100 ******************************************************************************/
1101
1102static ACPI_STATUS
1103AcpiDbWalkAndMatchName (
1104    ACPI_HANDLE             ObjHandle,
1105    UINT32                  NestingLevel,
1106    void                    *Context,
1107    void                    **ReturnValue)
1108{
1109    ACPI_STATUS             Status;
1110    char                    *RequestedName = (char *) Context;
1111    UINT32                  i;
1112    ACPI_BUFFER             Buffer;
1113    ACPI_WALK_INFO          Info;
1114
1115
1116    /* Check for a name match */
1117
1118    for (i = 0; i < 4; i++)
1119    {
1120        /* Wildcard support */
1121
1122        if ((RequestedName[i] != '?') &&
1123            (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1124        {
1125            /* No match, just exit */
1126
1127            return (AE_OK);
1128        }
1129    }
1130
1131    /* Get the full pathname to this object */
1132
1133    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1134    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1135    if (ACPI_FAILURE (Status))
1136    {
1137        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1138    }
1139    else
1140    {
1141        Info.OwnerId = ACPI_OWNER_ID_MAX;
1142        Info.DebugLevel = ACPI_UINT32_MAX;
1143        Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1144
1145        AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1146        (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1147        ACPI_FREE (Buffer.Pointer);
1148    }
1149
1150    return (AE_OK);
1151}
1152
1153
1154/*******************************************************************************
1155 *
1156 * FUNCTION:    AcpiDbFindNameInNamespace
1157 *
1158 * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
1159 *                                wildcards are supported.
1160 *
1161 * RETURN:      None
1162 *
1163 * DESCRIPTION: Search the namespace for a given name (with wildcards)
1164 *
1165 ******************************************************************************/
1166
1167ACPI_STATUS
1168AcpiDbFindNameInNamespace (
1169    char                    *NameArg)
1170{
1171
1172    if (ACPI_STRLEN (NameArg) > 4)
1173    {
1174        AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1175        return (AE_OK);
1176    }
1177
1178    /* Walk the namespace from the root */
1179
1180    AcpiUtStrupr (NameArg);
1181    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1182                        AcpiDbWalkAndMatchName, NameArg, NULL);
1183
1184    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1185    return (AE_OK);
1186}
1187
1188
1189/*******************************************************************************
1190 *
1191 * FUNCTION:    AcpiDbSetScope
1192 *
1193 * PARAMETERS:  Name                - New scope path
1194 *
1195 * RETURN:      Status
1196 *
1197 * DESCRIPTION: Set the "current scope" as maintained by this utility.
1198 *              The scope is used as a prefix to ACPI paths.
1199 *
1200 ******************************************************************************/
1201
1202void
1203AcpiDbSetScope (
1204    char                    *Name)
1205{
1206    ACPI_STATUS             Status;
1207    ACPI_NAMESPACE_NODE     *Node;
1208
1209
1210    if (!Name || Name[0] == 0)
1211    {
1212        AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1213        return;
1214    }
1215
1216    AcpiDbPrepNamestring (Name);
1217
1218    if (Name[0] == '\\')
1219    {
1220        /* Validate new scope from the root */
1221
1222        Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
1223                    &Node);
1224        if (ACPI_FAILURE (Status))
1225        {
1226            goto ErrorExit;
1227        }
1228
1229        ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1230        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1231    }
1232    else
1233    {
1234        /* Validate new scope relative to old scope */
1235
1236        Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
1237                    &Node);
1238        if (ACPI_FAILURE (Status))
1239        {
1240            goto ErrorExit;
1241        }
1242
1243        ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1244        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1245    }
1246
1247    AcpiGbl_DbScopeNode = Node;
1248    AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1249    return;
1250
1251ErrorExit:
1252
1253    AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1254        Name, AcpiFormatException (Status));
1255}
1256
1257
1258/*******************************************************************************
1259 *
1260 * FUNCTION:    AcpiDmCompareAmlResources
1261 *
1262 * PARAMETERS:  Aml1Buffer          - Contains first resource list
1263 *              Aml1BufferLength    - Length of first resource list
1264 *              Aml2Buffer          - Contains second resource list
1265 *              Aml2BufferLength    - Length of second resource list
1266 *
1267 * RETURN:      None
1268 *
1269 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1270 *              order to isolate a miscompare to an individual resource)
1271 *
1272 ******************************************************************************/
1273
1274static void
1275AcpiDmCompareAmlResources (
1276    UINT8                   *Aml1Buffer,
1277    ACPI_RSDESC_SIZE        Aml1BufferLength,
1278    UINT8                   *Aml2Buffer,
1279    ACPI_RSDESC_SIZE        Aml2BufferLength)
1280{
1281    UINT8                   *Aml1;
1282    UINT8                   *Aml2;
1283    ACPI_RSDESC_SIZE        Aml1Length;
1284    ACPI_RSDESC_SIZE        Aml2Length;
1285    ACPI_RSDESC_SIZE        Offset = 0;
1286    UINT8                   ResourceType;
1287    UINT32                  Count = 0;
1288
1289
1290    /* Compare overall buffer sizes (may be different due to size rounding) */
1291
1292    if (Aml1BufferLength != Aml2BufferLength)
1293    {
1294        AcpiOsPrintf (
1295            "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1296            Aml1BufferLength, Aml2BufferLength);
1297    }
1298
1299    Aml1 = Aml1Buffer;
1300    Aml2 = Aml2Buffer;
1301
1302    /* Walk the descriptor lists, comparing each descriptor */
1303
1304    while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1305    {
1306        /* Get the lengths of each descriptor */
1307
1308        Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1309        Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1310        ResourceType = AcpiUtGetResourceType (Aml1);
1311
1312        /* Check for descriptor length match */
1313
1314        if (Aml1Length != Aml2Length)
1315        {
1316            AcpiOsPrintf (
1317                "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1318                Count, ResourceType, Offset, Aml1Length, Aml2Length);
1319        }
1320
1321        /* Check for descriptor byte match */
1322
1323        else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1324        {
1325            AcpiOsPrintf (
1326                "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1327                Count, ResourceType, Offset);
1328        }
1329
1330        /* Exit on EndTag descriptor */
1331
1332        if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1333        {
1334            return;
1335        }
1336
1337        /* Point to next descriptor in each buffer */
1338
1339        Count++;
1340        Offset += Aml1Length;
1341        Aml1 += Aml1Length;
1342        Aml2 += Aml2Length;
1343    }
1344}
1345
1346
1347/*******************************************************************************
1348 *
1349 * FUNCTION:    AcpiDmTestResourceConversion
1350 *
1351 * PARAMETERS:  Node            - Parent device node
1352 *              Name            - resource method name (_CRS)
1353 *
1354 * RETURN:      Status
1355 *
1356 * DESCRIPTION: Compare the original AML with a conversion of the AML to
1357 *              internal resource list, then back to AML.
1358 *
1359 ******************************************************************************/
1360
1361static ACPI_STATUS
1362AcpiDmTestResourceConversion (
1363    ACPI_NAMESPACE_NODE     *Node,
1364    char                    *Name)
1365{
1366    ACPI_STATUS             Status;
1367    ACPI_BUFFER             ReturnObj;
1368    ACPI_BUFFER             ResourceObj;
1369    ACPI_BUFFER             NewAml;
1370    ACPI_OBJECT             *OriginalAml;
1371
1372
1373    AcpiOsPrintf ("Resource Conversion Comparison:\n");
1374
1375    NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1376    ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1377    ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1378
1379    /* Get the original _CRS AML resource template */
1380
1381    Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1382    if (ACPI_FAILURE (Status))
1383    {
1384        AcpiOsPrintf ("Could not obtain %s: %s\n",
1385            Name, AcpiFormatException (Status));
1386        return (Status);
1387    }
1388
1389    /* Get the AML resource template, converted to internal resource structs */
1390
1391    Status = AcpiGetCurrentResources (Node, &ResourceObj);
1392    if (ACPI_FAILURE (Status))
1393    {
1394        AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1395            AcpiFormatException (Status));
1396        goto Exit1;
1397    }
1398
1399    /* Convert internal resource list to external AML resource template */
1400
1401    Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1402    if (ACPI_FAILURE (Status))
1403    {
1404        AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1405            AcpiFormatException (Status));
1406        goto Exit2;
1407    }
1408
1409    /* Compare original AML to the newly created AML resource list */
1410
1411    OriginalAml = ReturnObj.Pointer;
1412
1413    AcpiDmCompareAmlResources (
1414        OriginalAml->Buffer.Pointer, OriginalAml->Buffer.Length,
1415        NewAml.Pointer, NewAml.Length);
1416
1417    /* Cleanup and exit */
1418
1419    ACPI_FREE (NewAml.Pointer);
1420Exit2:
1421    ACPI_FREE (ResourceObj.Pointer);
1422Exit1:
1423    ACPI_FREE (ReturnObj.Pointer);
1424    return (Status);
1425}
1426
1427
1428/*******************************************************************************
1429 *
1430 * FUNCTION:    AcpiDbDisplayResources
1431 *
1432 * PARAMETERS:  ObjectArg       - String with hex value of the object
1433 *
1434 * RETURN:      None
1435 *
1436 * DESCRIPTION: Display the resource objects associated with a device.
1437 *
1438 ******************************************************************************/
1439
1440void
1441AcpiDbDisplayResources (
1442    char                    *ObjectArg)
1443{
1444    ACPI_NAMESPACE_NODE     *Node;
1445    ACPI_STATUS             Status;
1446    ACPI_BUFFER             ReturnObj;
1447
1448
1449    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1450    AcpiDbgLevel |= ACPI_LV_RESOURCES;
1451
1452    /* Convert string to object pointer */
1453
1454    Node = AcpiDbConvertToNode (ObjectArg);
1455    if (!Node)
1456    {
1457        return;
1458    }
1459
1460    /* Prepare for a return object of arbitrary size */
1461
1462    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1463    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1464
1465    /* _PRT */
1466
1467    AcpiOsPrintf ("Evaluating _PRT\n");
1468
1469    /* Check if _PRT exists */
1470
1471    Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1472    if (ACPI_FAILURE (Status))
1473    {
1474        AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1475            AcpiFormatException (Status));
1476        goto GetCrs;
1477    }
1478
1479    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1480    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1481
1482    Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1483    if (ACPI_FAILURE (Status))
1484    {
1485        AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1486            AcpiFormatException (Status));
1487        goto GetCrs;
1488    }
1489
1490    AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1491
1492
1493    /* _CRS */
1494
1495GetCrs:
1496    AcpiOsPrintf ("Evaluating _CRS\n");
1497
1498    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1499    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1500
1501    /* Check if _CRS exists */
1502
1503    Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1504    if (ACPI_FAILURE (Status))
1505    {
1506        AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1507            AcpiFormatException (Status));
1508        goto GetPrs;
1509    }
1510
1511    /* Get the _CRS resource list */
1512
1513    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1514    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1515
1516    Status = AcpiGetCurrentResources (Node, &ReturnObj);
1517    if (ACPI_FAILURE (Status))
1518    {
1519        AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1520            AcpiFormatException (Status));
1521        goto GetPrs;
1522    }
1523
1524    /* Dump the _CRS resource list */
1525
1526    AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1527        ReturnObj.Pointer));
1528
1529    /*
1530     * Perform comparison of original AML to newly created AML. This tests both
1531     * the AML->Resource conversion and the Resource->Aml conversion.
1532     */
1533    Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1534
1535    /* Execute _SRS with the resource list */
1536
1537    Status = AcpiSetCurrentResources (Node, &ReturnObj);
1538    if (ACPI_FAILURE (Status))
1539    {
1540        AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1541            AcpiFormatException (Status));
1542        goto GetPrs;
1543    }
1544
1545
1546    /* _PRS */
1547
1548GetPrs:
1549    AcpiOsPrintf ("Evaluating _PRS\n");
1550
1551    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1552    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1553
1554    /* Check if _PRS exists */
1555
1556    Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1557    if (ACPI_FAILURE (Status))
1558    {
1559        AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1560            AcpiFormatException (Status));
1561        goto Cleanup;
1562    }
1563
1564    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1565    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1566
1567    Status = AcpiGetPossibleResources (Node, &ReturnObj);
1568    if (ACPI_FAILURE (Status))
1569    {
1570        AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1571            AcpiFormatException (Status));
1572        goto Cleanup;
1573    }
1574
1575    AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1576
1577Cleanup:
1578
1579    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1580    return;
1581}
1582
1583
1584/*******************************************************************************
1585 *
1586 * FUNCTION:    AcpiDbIntegrityWalk
1587 *
1588 * PARAMETERS:  Callback from WalkNamespace
1589 *
1590 * RETURN:      Status
1591 *
1592 * DESCRIPTION: Examine one NS node for valid values.
1593 *
1594 ******************************************************************************/
1595
1596static ACPI_STATUS
1597AcpiDbIntegrityWalk (
1598    ACPI_HANDLE             ObjHandle,
1599    UINT32                  NestingLevel,
1600    void                    *Context,
1601    void                    **ReturnValue)
1602{
1603    ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1604    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1605    ACPI_OPERAND_OBJECT     *Object;
1606
1607
1608    Info->Nodes++;
1609    if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1610    {
1611        AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s]\n",
1612            Node, AcpiUtGetDescriptorName (Node));
1613    }
1614
1615    if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1616    {
1617        AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1618            Node, Node->Type);
1619    }
1620
1621    if (!AcpiUtValidAcpiName (Node->Name.Integer))
1622    {
1623        AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1624    }
1625
1626    Object = AcpiNsGetAttachedObject (Node);
1627    if (Object)
1628    {
1629        Info->Objects++;
1630        if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1631        {
1632            AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1633                Object, AcpiUtGetDescriptorName (Object));
1634        }
1635    }
1636
1637    return (AE_OK);
1638}
1639
1640
1641/*******************************************************************************
1642 *
1643 * FUNCTION:    AcpiDbCheckIntegrity
1644 *
1645 * PARAMETERS:  None
1646 *
1647 * RETURN:      None
1648 *
1649 * DESCRIPTION: Check entire namespace for data structure integrity
1650 *
1651 ******************************************************************************/
1652
1653void
1654AcpiDbCheckIntegrity (
1655    void)
1656{
1657    ACPI_INTEGRITY_INFO     Info = {0,0};
1658
1659    /* Search all nodes in namespace */
1660
1661    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1662                    AcpiDbIntegrityWalk, (void *) &Info, NULL);
1663
1664    AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n",
1665        Info.Nodes, Info.Objects);
1666}
1667
1668
1669/*******************************************************************************
1670 *
1671 * FUNCTION:    AcpiDbGenerateGpe
1672 *
1673 * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1674 *              BlockArg        - GPE block number, ascii string
1675 *                                0 or 1 for FADT GPE blocks
1676 *
1677 * RETURN:      None
1678 *
1679 * DESCRIPTION: Generate a GPE
1680 *
1681 ******************************************************************************/
1682
1683void
1684AcpiDbGenerateGpe (
1685    char                    *GpeArg,
1686    char                    *BlockArg)
1687{
1688    UINT32                  BlockNumber;
1689    UINT32                  GpeNumber;
1690    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1691
1692
1693    GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1694    BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1695
1696
1697    GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1698        GpeNumber);
1699    if (!GpeEventInfo)
1700    {
1701        AcpiOsPrintf ("Invalid GPE\n");
1702        return;
1703    }
1704
1705    (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1706}
1707
1708
1709/*******************************************************************************
1710 *
1711 * FUNCTION:    AcpiDbBusWalk
1712 *
1713 * PARAMETERS:  Callback from WalkNamespace
1714 *
1715 * RETURN:      Status
1716 *
1717 * DESCRIPTION: Display info about device objects that have a corresponding
1718 *              _PRT method.
1719 *
1720 ******************************************************************************/
1721
1722static ACPI_STATUS
1723AcpiDbBusWalk (
1724    ACPI_HANDLE             ObjHandle,
1725    UINT32                  NestingLevel,
1726    void                    *Context,
1727    void                    **ReturnValue)
1728{
1729    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1730    ACPI_STATUS             Status;
1731    ACPI_BUFFER             Buffer;
1732    ACPI_INTEGER            ADR;
1733    ACPI_DEVICE_ID          Id;
1734    ACPI_COMPATIBLE_ID_LIST *Cid;
1735    ACPI_NAMESPACE_NODE     *TempNode;
1736
1737
1738    /* Exit if there is no _PRT under this device */
1739
1740    Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
1741                ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
1742    if (ACPI_FAILURE (Status))
1743    {
1744        return (AE_OK);
1745    }
1746
1747    /* Get the full path to this device object */
1748
1749    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1750    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1751    if (ACPI_FAILURE (Status))
1752    {
1753        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1754        return (AE_OK);
1755    }
1756
1757    /* Display the full path */
1758
1759    AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer);
1760    ACPI_FREE (Buffer.Pointer);
1761
1762    /* _PRT info */
1763
1764    AcpiOsPrintf ("_PRT=%p", TempNode);
1765
1766    /* Get the _ADR value */
1767
1768    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR);
1769    if (ACPI_FAILURE (Status))
1770    {
1771        AcpiOsPrintf (" No _ADR      ");
1772    }
1773    else
1774    {
1775        AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR);
1776    }
1777
1778    /* Get the _HID if present */
1779
1780    Status = AcpiUtExecute_HID (Node, &Id);
1781    if (ACPI_SUCCESS (Status))
1782    {
1783        AcpiOsPrintf (" _HID=%s", Id.Value);
1784    }
1785    else
1786    {
1787        AcpiOsPrintf ("             ");
1788    }
1789
1790    /* Get the _UID if present */
1791
1792    Status = AcpiUtExecute_UID (Node, &Id);
1793    if (ACPI_SUCCESS (Status))
1794    {
1795        AcpiOsPrintf (" _UID=%s", Id.Value);
1796    }
1797
1798    /* Get the _CID if present */
1799
1800    Status = AcpiUtExecute_CID (Node, &Cid);
1801    if (ACPI_SUCCESS (Status))
1802    {
1803        AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value);
1804        ACPI_FREE (Cid);
1805    }
1806
1807    AcpiOsPrintf ("\n");
1808    return (AE_OK);
1809}
1810
1811
1812/*******************************************************************************
1813 *
1814 * FUNCTION:    AcpiDbGetBusInfo
1815 *
1816 * PARAMETERS:  None
1817 *
1818 * RETURN:      None
1819 *
1820 * DESCRIPTION: Display info about system busses.
1821 *
1822 ******************************************************************************/
1823
1824void
1825AcpiDbGetBusInfo (
1826    void)
1827{
1828    /* Search all nodes in namespace */
1829
1830    (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1831                    AcpiDbBusWalk, NULL, NULL);
1832}
1833
1834#endif /* ACPI_DEBUGGER */
1835