dbcmds.c revision 129684
1/*******************************************************************************
2 *
3 * Module Name: dbcmds - debug commands and output routines
4 *              $Revision: 112 $
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
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#ifdef ACPI_DEBUGGER
128
129#define _COMPONENT          ACPI_CA_DEBUGGER
130        ACPI_MODULE_NAME    ("dbcmds")
131
132
133/*
134 * Arguments for the Objects command
135 * These object types map directly to the ACPI_TYPES
136 */
137
138static ARGUMENT_INFO        AcpiDbObjectTypes [] =
139{
140    {"ANY"},
141    {"NUMBERS"},
142    {"STRINGS"},
143    {"BUFFERS"},
144    {"PACKAGES"},
145    {"FIELDS"},
146    {"DEVICES"},
147    {"EVENTS"},
148    {"METHODS"},
149    {"MUTEXES"},
150    {"REGIONS"},
151    {"POWERRESOURCES"},
152    {"PROCESSORS"},
153    {"THERMALZONES"},
154    {"BUFFERFIELDS"},
155    {"DDBHANDLES"},
156    {NULL}           /* Must be null terminated */
157};
158
159
160ACPI_STATUS
161AcpiDbSleep (
162    char                    *ObjectArg)
163{
164    ACPI_STATUS             Status;
165    UINT8                   SleepState;
166
167
168    SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
169
170    AcpiOsPrintf ("**** Prepare to sleep ****\n");
171    Status = AcpiEnterSleepStatePrep (SleepState);
172    if (ACPI_FAILURE (Status))
173    {
174        return (Status);
175    }
176
177    AcpiOsPrintf ("**** Going to sleep ****\n");
178    Status = AcpiEnterSleepState (SleepState);
179    if (ACPI_FAILURE (Status))
180    {
181        return (Status);
182    }
183
184    AcpiOsPrintf ("**** returning from sleep ****\n");
185    Status = AcpiLeaveSleepState (SleepState);
186
187    return (Status);
188}
189
190
191/*******************************************************************************
192 *
193 * FUNCTION:    AcpiDbWalkForReferences
194 *
195 * PARAMETERS:  Callback from WalkNamespace
196 *
197 * RETURN:      Status
198 *
199 * DESCRIPTION: Check if this namespace object refers to the target object
200 *              that is passed in as the context value.
201 *
202 * Note: Currently doesn't check subobjects within the Node's object
203 *
204 ******************************************************************************/
205
206ACPI_STATUS
207AcpiDbWalkForReferences (
208    ACPI_HANDLE             ObjHandle,
209    UINT32                  NestingLevel,
210    void                    *Context,
211    void                    **ReturnValue)
212{
213    ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
214    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
215
216
217    /* Check for match against the namespace node itself */
218
219    if (Node == (void *) ObjDesc)
220    {
221        AcpiOsPrintf ("Object is a Node [%4.4s]\n",
222            AcpiUtGetNodeName (Node));
223    }
224
225    /* Check for match against the object attached to the node */
226
227    if (AcpiNsGetAttachedObject (Node) == ObjDesc)
228    {
229        AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
230            Node, AcpiUtGetNodeName (Node));
231    }
232
233    return (AE_OK);
234}
235
236
237/*******************************************************************************
238 *
239 * FUNCTION:    AcpiDbFindReferences
240 *
241 * PARAMETERS:  ObjectArg       - String with hex value of the object
242 *
243 * RETURN:      None
244 *
245 * DESCRIPTION: Search namespace for all references to the input object
246 *
247 ******************************************************************************/
248
249void
250AcpiDbFindReferences (
251    char                    *ObjectArg)
252{
253    ACPI_OPERAND_OBJECT     *ObjDesc;
254
255
256    /* Convert string to object pointer */
257
258    ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
259
260    /* Search all nodes in namespace */
261
262    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
263                    AcpiDbWalkForReferences, (void *) ObjDesc, NULL);
264}
265
266
267/*******************************************************************************
268 *
269 * FUNCTION:    AcpiDbDisplayLocks
270 *
271 * PARAMETERS:  None
272 *
273 * RETURN:      None
274 *
275 * DESCRIPTION: Display information about internal mutexes.
276 *
277 ******************************************************************************/
278
279void
280AcpiDbDisplayLocks (void)
281{
282    UINT32                  i;
283
284
285    for (i = 0; i < MAX_MUTEX; i++)
286    {
287        AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
288                    AcpiGbl_MutexInfo[i].OwnerId == ACPI_MUTEX_NOT_ACQUIRED
289                        ? "Locked" : "Unlocked");
290    }
291}
292
293
294/*******************************************************************************
295 *
296 * FUNCTION:    AcpiDbDisplayTableInfo
297 *
298 * PARAMETERS:  TableArg        - String with name of table to be displayed
299 *
300 * RETURN:      None
301 *
302 * DESCRIPTION: Display information about loaded tables.  Current
303 *              implementation displays all loaded tables.
304 *
305 ******************************************************************************/
306
307void
308AcpiDbDisplayTableInfo (
309    char                    *TableArg)
310{
311    UINT32                  i;
312    ACPI_TABLE_DESC         *TableDesc;
313
314
315    for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
316    {
317        TableDesc = AcpiGbl_TableLists[i].Next;
318        while (TableDesc)
319        {
320            AcpiOsPrintf ( "%s at %p length %.5X",
321                    AcpiGbl_TableData[i].Name, TableDesc->Pointer,
322                    (UINT32) TableDesc->Length);
323
324            if (i != ACPI_TABLE_FACS)
325            {
326                AcpiOsPrintf (" OemID=%6s TableId=%8s OemRevision=%8.8X",
327                        TableDesc->Pointer->OemId,
328                        TableDesc->Pointer->OemTableId,
329                        TableDesc->Pointer->OemRevision);
330            }
331            AcpiOsPrintf ("\n");
332
333            TableDesc = TableDesc->Next;
334        }
335    }
336}
337
338
339/*******************************************************************************
340 *
341 * FUNCTION:    AcpiDbUnloadAcpiTable
342 *
343 * PARAMETERS:  TableArg        - Name of the table to be unloaded
344 *              InstanceArg     - Which instance of the table to unload (if
345 *                                there are multiple tables of the same type)
346 *
347 * RETURN:      Nonde
348 *
349 * DESCRIPTION: Unload an ACPI table.
350 *              Instance is not implemented
351 *
352 ******************************************************************************/
353
354void
355AcpiDbUnloadAcpiTable (
356    char                    *TableArg,
357    char                    *InstanceArg)
358{
359    UINT32                  i;
360    ACPI_STATUS             Status;
361
362
363    /* Search all tables for the target type */
364
365    for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
366    {
367        if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
368                AcpiGbl_TableData[i].SigLength))
369        {
370            /* Found the table, unload it */
371
372            Status = AcpiUnloadTable (i);
373            if (ACPI_SUCCESS (Status))
374            {
375                AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
376            }
377            else
378            {
379                AcpiOsPrintf ("%s, while unloading [%s]\n",
380                    AcpiFormatException (Status), TableArg);
381            }
382
383            return;
384        }
385    }
386
387    AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
388}
389
390
391/*******************************************************************************
392 *
393 * FUNCTION:    AcpiDbSetMethodBreakpoint
394 *
395 * PARAMETERS:  Location            - AML offset of breakpoint
396 *              WalkState           - Current walk info
397 *              Op                  - Current Op (from parse walk)
398 *
399 * RETURN:      None
400 *
401 * DESCRIPTION: Set a breakpoint in a control method at the specified
402 *              AML offset
403 *
404 ******************************************************************************/
405
406void
407AcpiDbSetMethodBreakpoint (
408    char                    *Location,
409    ACPI_WALK_STATE         *WalkState,
410    ACPI_PARSE_OBJECT       *Op)
411{
412    UINT32                  Address;
413
414
415    if (!Op)
416    {
417        AcpiOsPrintf ("There is no method currently executing\n");
418        return;
419    }
420
421    /* Get and verify the breakpoint address */
422
423    Address = ACPI_STRTOUL (Location, NULL, 16);
424    if (Address <= Op->Common.AmlOffset)
425    {
426        AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n", Address, Op->Common.AmlOffset);
427    }
428
429    /* Save breakpoint in current walk */
430
431    WalkState->UserBreakpoint = Address;
432    AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
433}
434
435
436/*******************************************************************************
437 *
438 * FUNCTION:    AcpiDbSetMethodCallBreakpoint
439 *
440 * PARAMETERS:  Op                  - Current Op (from parse walk)
441 *
442 * RETURN:      None
443 *
444 * DESCRIPTION: Set a breakpoint in a control method at the specified
445 *              AML offset
446 *
447 ******************************************************************************/
448
449void
450AcpiDbSetMethodCallBreakpoint (
451    ACPI_PARSE_OBJECT       *Op)
452{
453
454
455    if (!Op)
456    {
457        AcpiOsPrintf ("There is no method currently executing\n");
458        return;
459    }
460
461    AcpiGbl_StepToNextCall = TRUE;
462}
463
464
465/*******************************************************************************
466 *
467 * FUNCTION:    AcpiDbDisassembleAml
468 *
469 * PARAMETERS:  Statements          - Number of statements to disassemble
470 *              Op                  - Current Op (from parse walk)
471 *
472 * RETURN:      None
473 *
474 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
475 *              of statements specified.
476 *
477 ******************************************************************************/
478
479void
480AcpiDbDisassembleAml (
481    char                    *Statements,
482    ACPI_PARSE_OBJECT       *Op)
483{
484    UINT32                  NumStatements = 8;
485
486
487    if (!Op)
488    {
489        AcpiOsPrintf ("There is no method currently executing\n");
490        return;
491    }
492
493    if (Statements)
494    {
495        NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
496    }
497
498    AcpiDmDisassemble (NULL, Op, NumStatements);
499}
500
501
502/*******************************************************************************
503 *
504 * FUNCTION:    AcpiDbDumpNamespace
505 *
506 * PARAMETERS:  StartArg        - Node to begin namespace dump
507 *              DepthArg        - Maximum tree depth to be dumped
508 *
509 * RETURN:      None
510 *
511 * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
512 *              with type and other information.
513 *
514 ******************************************************************************/
515
516void
517AcpiDbDumpNamespace (
518    char                    *StartArg,
519    char                    *DepthArg)
520{
521    ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
522    UINT32                  MaxDepth = ACPI_UINT32_MAX;
523
524
525    /* No argument given, just start at the root and dump entire namespace */
526
527    if (StartArg)
528    {
529        /* Check if numeric argument, must be a Node */
530
531        if ((StartArg[0] >= 0x30) && (StartArg[0] <= 0x39))
532        {
533            SubtreeEntry = ACPI_TO_POINTER (ACPI_STRTOUL (StartArg, NULL, 16));
534            if (!AcpiOsReadable (SubtreeEntry, sizeof (ACPI_NAMESPACE_NODE)))
535            {
536                AcpiOsPrintf ("Address %p is invalid in this address space\n", SubtreeEntry);
537                return;
538            }
539
540            if (ACPI_GET_DESCRIPTOR_TYPE (SubtreeEntry) != ACPI_DESC_TYPE_NAMED)
541            {
542                AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
543                        SubtreeEntry, AcpiUtGetDescriptorName (SubtreeEntry));
544                return;
545            }
546        }
547        else
548        {
549            /* Alpha argument */
550            /* The parameter is a name string that must be resolved to a Named obj*/
551
552            SubtreeEntry = AcpiDbLocalNsLookup (StartArg);
553            if (!SubtreeEntry)
554            {
555                SubtreeEntry = AcpiGbl_RootNode;
556            }
557        }
558
559        /* Now we can check for the depth argument */
560
561        if (DepthArg)
562        {
563            MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
564        }
565    }
566
567    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
568    AcpiOsPrintf ("ACPI Namespace (from %p subtree):\n", SubtreeEntry);
569
570    /* Display the subtree */
571
572    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
573    AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, ACPI_UINT32_MAX, SubtreeEntry);
574    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
575}
576
577
578/*******************************************************************************
579 *
580 * FUNCTION:    AcpiDbDumpNamespaceByOwner
581 *
582 * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
583 *              DepthArg        - Maximum tree depth to be dumped
584 *
585 * RETURN:      None
586 *
587 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
588 *
589 ******************************************************************************/
590
591void
592AcpiDbDumpNamespaceByOwner (
593    char                    *OwnerArg,
594    char                    *DepthArg)
595{
596    ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
597    UINT32                  MaxDepth = ACPI_UINT32_MAX;
598    UINT16                  OwnerId;
599
600
601    OwnerId = (UINT16) ACPI_STRTOUL (OwnerArg, NULL, 0);
602
603    /* Now we can check for the depth argument */
604
605    if (DepthArg)
606    {
607        MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
608    }
609
610    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
611    AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
612
613    /* Display the subtree */
614
615    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
616    AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId, SubtreeEntry);
617    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
618}
619
620
621/*******************************************************************************
622 *
623 * FUNCTION:    AcpiDbSendNotify
624 *
625 * PARAMETERS:  Name            - Name of ACPI object to send the notify to
626 *              Value           - Value of the notify to send.
627 *
628 * RETURN:      None
629 *
630 * DESCRIPTION: Send an ACPI notification.  The value specified is sent to the
631 *              named object as an ACPI notify.
632 *
633 ******************************************************************************/
634
635void
636AcpiDbSendNotify (
637    char                    *Name,
638    UINT32                  Value)
639{
640    ACPI_NAMESPACE_NODE     *Node;
641    ACPI_STATUS             Status;
642
643
644    /* Translate name to an Named object */
645
646    Node = AcpiDbLocalNsLookup (Name);
647    if (!Node)
648    {
649        return;
650    }
651
652    /* Decode Named object type */
653
654    switch (Node->Type)
655    {
656    case ACPI_TYPE_DEVICE:
657    case ACPI_TYPE_THERMAL:
658
659         /* Send the notify */
660
661        Status = AcpiEvQueueNotifyRequest (Node, Value);
662        if (ACPI_FAILURE (Status))
663        {
664            AcpiOsPrintf ("Could not queue notify\n");
665        }
666        break;
667
668    default:
669        AcpiOsPrintf ("Named object is not a device or a thermal object\n");
670        break;
671    }
672}
673
674
675/*******************************************************************************
676 *
677 * FUNCTION:    AcpiDbSetMethodData
678 *
679 * PARAMETERS:  TypeArg         - L for local, A for argument
680 *              IndexArg        - which one
681 *              ValueArg        - Value to set.
682 *
683 * RETURN:      None
684 *
685 * DESCRIPTION: Set a local or argument for the running control method.
686 *              NOTE: only object supported is Number.
687 *
688 ******************************************************************************/
689
690void
691AcpiDbSetMethodData (
692    char                    *TypeArg,
693    char                    *IndexArg,
694    char                    *ValueArg)
695{
696    char                    Type;
697    UINT32                  Index;
698    UINT32                  Value;
699    ACPI_WALK_STATE         *WalkState;
700    ACPI_OPERAND_OBJECT     *ObjDesc;
701    ACPI_STATUS             Status;
702
703
704    /* Validate TypeArg */
705
706    ACPI_STRUPR (TypeArg);
707    Type = TypeArg[0];
708    if ((Type != 'L') &&
709        (Type != 'A'))
710    {
711        AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
712        return;
713    }
714
715    /* Get the index and value */
716
717    Index = ACPI_STRTOUL (IndexArg, NULL, 16);
718    Value = ACPI_STRTOUL (ValueArg, NULL, 16);
719
720    WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
721    if (!WalkState)
722    {
723        AcpiOsPrintf ("There is no method currently executing\n");
724        return;
725    }
726
727    /* Create and initialize the new object */
728
729    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
730    if (!ObjDesc)
731    {
732        AcpiOsPrintf ("Could not create an internal object\n");
733        return;
734    }
735
736    ObjDesc->Integer.Value = Value;
737
738    /* Store the new object into the target */
739
740    switch (Type)
741    {
742    case 'A':
743
744        /* Set a method argument */
745
746        if (Index > ACPI_METHOD_MAX_ARG)
747        {
748            AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index);
749            return;
750        }
751
752        Status = AcpiDsStoreObjectToLocal (AML_ARG_OP, Index, ObjDesc, WalkState);
753        if (ACPI_FAILURE (Status))
754        {
755            return;
756        }
757
758        ObjDesc = WalkState->Arguments[Index].Object;
759
760        AcpiOsPrintf ("Arg%d: ", Index);
761        AcpiDmDisplayInternalObject (ObjDesc, WalkState);
762        break;
763
764    case 'L':
765
766        /* Set a method local */
767
768        if (Index > ACPI_METHOD_MAX_LOCAL)
769        {
770            AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index);
771            return;
772        }
773
774        Status = AcpiDsStoreObjectToLocal (AML_LOCAL_OP, Index, ObjDesc, WalkState);
775        if (ACPI_FAILURE (Status))
776        {
777            return;
778        }
779
780        ObjDesc = WalkState->LocalVariables[Index].Object;
781
782        AcpiOsPrintf ("Local%d: ", Index);
783        AcpiDmDisplayInternalObject (ObjDesc, WalkState);
784        break;
785
786    default:
787        break;
788    }
789}
790
791
792/*******************************************************************************
793 *
794 * FUNCTION:    AcpiDbWalkForSpecificObjects
795 *
796 * PARAMETERS:  Callback from WalkNamespace
797 *
798 * RETURN:      Status
799 *
800 * DESCRIPTION: Display short info about objects in the namespace
801 *
802 ******************************************************************************/
803
804ACPI_STATUS
805AcpiDbWalkForSpecificObjects (
806    ACPI_HANDLE             ObjHandle,
807    UINT32                  NestingLevel,
808    void                    *Context,
809    void                    **ReturnValue)
810{
811    ACPI_OPERAND_OBJECT     *ObjDesc;
812    ACPI_STATUS             Status;
813    ACPI_BUFFER             Buffer;
814
815
816    ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjHandle);
817
818    /* Get and display the full pathname to this object */
819
820    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
821    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
822    if (ACPI_FAILURE (Status))
823    {
824        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
825        return (AE_OK);
826    }
827
828    AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
829    ACPI_MEM_FREE (Buffer.Pointer);
830
831    /* Display short information about the object */
832
833    if (ObjDesc)
834    {
835        switch (ACPI_GET_OBJECT_TYPE (ObjDesc))
836        {
837        case ACPI_TYPE_METHOD:
838            AcpiOsPrintf ("  #Args %d  Concurrency %X",
839                    ObjDesc->Method.ParamCount, ObjDesc->Method.Concurrency);
840            break;
841
842        case ACPI_TYPE_INTEGER:
843            AcpiOsPrintf ("  Value %8.8X%8.8X",
844                    ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
845            break;
846
847        case ACPI_TYPE_STRING:
848            AcpiOsPrintf ("  \"%s\"", ObjDesc->String.Pointer);
849            break;
850
851        case ACPI_TYPE_REGION:
852            AcpiOsPrintf ("  SpaceId %X Length %X Address %8.8X%8.8X",
853                    ObjDesc->Region.SpaceId,
854                    ObjDesc->Region.Length,
855                    ACPI_FORMAT_UINT64 (ObjDesc->Region.Address));
856            break;
857
858        case ACPI_TYPE_PACKAGE:
859            AcpiOsPrintf ("  #Elements %X", ObjDesc->Package.Count);
860            break;
861
862        case ACPI_TYPE_BUFFER:
863            AcpiOsPrintf ("  Length %X", ObjDesc->Buffer.Length);
864            break;
865
866        default:
867            /* Ignore other object types */
868            break;
869        }
870    }
871
872    AcpiOsPrintf ("\n");
873    return (AE_OK);
874}
875
876
877/*******************************************************************************
878 *
879 * FUNCTION:    AcpiDbDisplayObjects
880 *
881 * PARAMETERS:  ObjTypeArg          - Type of object to display
882 *              DisplayCountArg     - Max depth to display
883 *
884 * RETURN:      None
885 *
886 * DESCRIPTION: Display objects in the namespace of the requested type
887 *
888 ******************************************************************************/
889
890ACPI_STATUS
891AcpiDbDisplayObjects (
892    char                    *ObjTypeArg,
893    char                    *DisplayCountArg)
894{
895    ACPI_OBJECT_TYPE        Type;
896
897
898    /* Get the object type */
899
900    Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
901    if (Type == ACPI_TYPE_NOT_FOUND)
902    {
903        AcpiOsPrintf ("Invalid or unsupported argument\n");
904        return (AE_OK);
905    }
906
907    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
908    AcpiOsPrintf ("Objects of type [%s] defined in the current ACPI Namespace: \n",
909        AcpiUtGetTypeName (Type));
910
911    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
912
913    /* Walk the namespace from the root */
914
915    (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
916                        AcpiDbWalkForSpecificObjects, (void *) &Type, NULL);
917
918    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
919    return (AE_OK);
920}
921
922
923/*******************************************************************************
924 *
925 * FUNCTION:    AcpiDbWalkAndMatchName
926 *
927 * PARAMETERS:  Callback from WalkNamespace
928 *
929 * RETURN:      Status
930 *
931 * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
932 *              are supported -- '?' matches any character.
933 *
934 ******************************************************************************/
935
936ACPI_STATUS
937AcpiDbWalkAndMatchName (
938    ACPI_HANDLE             ObjHandle,
939    UINT32                  NestingLevel,
940    void                    *Context,
941    void                    **ReturnValue)
942{
943    ACPI_STATUS             Status;
944    char                    *RequestedName = (char *) Context;
945    UINT32                  i;
946    ACPI_BUFFER             Buffer;
947
948
949    /* Check for a name match */
950
951    for (i = 0; i < 4; i++)
952    {
953        /* Wildcard support */
954
955        if ((RequestedName[i] != '?') &&
956            (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
957        {
958            /* No match, just exit */
959
960            return (AE_OK);
961        }
962    }
963
964    /* Get the full pathname to this object */
965
966    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
967    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
968    if (ACPI_FAILURE (Status))
969    {
970        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
971    }
972    else
973    {
974        AcpiOsPrintf ("%32s (%p) - %s\n", (char *) Buffer.Pointer, ObjHandle,
975            AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) ObjHandle)->Type));
976        ACPI_MEM_FREE (Buffer.Pointer);
977    }
978
979    return (AE_OK);
980}
981
982
983/*******************************************************************************
984 *
985 * FUNCTION:    AcpiDbFindNameInNamespace
986 *
987 * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
988 *                                wildcards are supported.
989 *
990 * RETURN:      None
991 *
992 * DESCRIPTION: Search the namespace for a given name (with wildcards)
993 *
994 ******************************************************************************/
995
996ACPI_STATUS
997AcpiDbFindNameInNamespace (
998    char                    *NameArg)
999{
1000
1001    if (ACPI_STRLEN (NameArg) > 4)
1002    {
1003        AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1004        return (AE_OK);
1005    }
1006
1007    /* Walk the namespace from the root */
1008
1009    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1010                        AcpiDbWalkAndMatchName, NameArg, NULL);
1011
1012    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1013    return (AE_OK);
1014}
1015
1016
1017/*******************************************************************************
1018 *
1019 * FUNCTION:    AcpiDbSetScope
1020 *
1021 * PARAMETERS:  Name                - New scope path
1022 *
1023 * RETURN:      Status
1024 *
1025 * DESCRIPTION: Set the "current scope" as maintained by this utility.
1026 *              The scope is used as a prefix to ACPI paths.
1027 *
1028 ******************************************************************************/
1029
1030void
1031AcpiDbSetScope (
1032    char                    *Name)
1033{
1034    ACPI_STATUS             Status;
1035    ACPI_NAMESPACE_NODE     *Node;
1036
1037
1038    if (!Name || Name[0] == 0)
1039    {
1040        AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1041        return;
1042    }
1043
1044    AcpiDbPrepNamestring (Name);
1045
1046    if (Name[0] == '\\')
1047    {
1048        /* Validate new scope from the root */
1049
1050        Status = AcpiNsGetNodeByPath (Name, AcpiGbl_RootNode, ACPI_NS_NO_UPSEARCH, &Node);
1051        if (ACPI_FAILURE (Status))
1052        {
1053            goto ErrorExit;
1054        }
1055
1056        ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1057        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1058    }
1059    else
1060    {
1061        /* Validate new scope relative to old scope */
1062
1063        Status = AcpiNsGetNodeByPath (Name, AcpiGbl_DbScopeNode, ACPI_NS_NO_UPSEARCH, &Node);
1064        if (ACPI_FAILURE (Status))
1065        {
1066            goto ErrorExit;
1067        }
1068
1069        ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1070        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1071    }
1072
1073    AcpiGbl_DbScopeNode = Node;
1074    AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1075    return;
1076
1077ErrorExit:
1078
1079    AcpiOsPrintf ("Could not attach scope: %s, %s\n", Name, AcpiFormatException (Status));
1080}
1081
1082
1083/*******************************************************************************
1084 *
1085 * FUNCTION:    AcpiDbDisplayResources
1086 *
1087 * PARAMETERS:  ObjectArg       - String with hex value of the object
1088 *
1089 * RETURN:      None
1090 *
1091 * DESCRIPTION: Display the resource objects associated with a device.
1092 *
1093 ******************************************************************************/
1094
1095void
1096AcpiDbDisplayResources (
1097    char                    *ObjectArg)
1098{
1099#if ACPI_MACHINE_WIDTH != 16
1100
1101    ACPI_OPERAND_OBJECT     *ObjDesc;
1102    ACPI_STATUS             Status;
1103    ACPI_BUFFER             ReturnObj;
1104
1105
1106    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1107    AcpiDbgLevel |= ACPI_LV_RESOURCES;
1108
1109    /* Convert string to object pointer */
1110
1111    ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
1112
1113    /* Prepare for a return object of arbitrary size */
1114
1115    ReturnObj.Pointer           = AcpiGbl_DbBuffer;
1116    ReturnObj.Length            = ACPI_DEBUG_BUFFER_SIZE;
1117
1118    /* _PRT */
1119
1120    AcpiOsPrintf ("Evaluating _PRT\n");
1121
1122    Status = AcpiEvaluateObject (ObjDesc, "_PRT", NULL, &ReturnObj);
1123    if (ACPI_FAILURE (Status))
1124    {
1125        AcpiOsPrintf ("Could not obtain _PRT: %s\n", AcpiFormatException (Status));
1126        goto GetCrs;
1127    }
1128
1129    ReturnObj.Pointer           = AcpiGbl_DbBuffer;
1130    ReturnObj.Length            = ACPI_DEBUG_BUFFER_SIZE;
1131
1132    Status = AcpiGetIrqRoutingTable (ObjDesc, &ReturnObj);
1133    if (ACPI_FAILURE (Status))
1134    {
1135        AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", AcpiFormatException (Status));
1136    }
1137    else
1138    {
1139        AcpiRsDumpIrqList ((UINT8 *) AcpiGbl_DbBuffer);
1140    }
1141
1142
1143    /* _CRS */
1144
1145GetCrs:
1146    AcpiOsPrintf ("Evaluating _CRS\n");
1147
1148    ReturnObj.Pointer           = AcpiGbl_DbBuffer;
1149    ReturnObj.Length            = ACPI_DEBUG_BUFFER_SIZE;
1150
1151    Status = AcpiEvaluateObject (ObjDesc, "_CRS", NULL, &ReturnObj);
1152    if (ACPI_FAILURE (Status))
1153    {
1154        AcpiOsPrintf ("Could not obtain _CRS: %s\n", AcpiFormatException (Status));
1155        goto GetPrs;
1156    }
1157
1158    ReturnObj.Pointer           = AcpiGbl_DbBuffer;
1159    ReturnObj.Length            = ACPI_DEBUG_BUFFER_SIZE;
1160
1161    Status = AcpiGetCurrentResources (ObjDesc, &ReturnObj);
1162    if (ACPI_FAILURE (Status))
1163    {
1164        AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", AcpiFormatException (Status));
1165        goto GetPrs;
1166    }
1167    else
1168    {
1169        AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1170    }
1171
1172    Status = AcpiSetCurrentResources (ObjDesc, &ReturnObj);
1173    if (ACPI_FAILURE (Status))
1174    {
1175        AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", AcpiFormatException (Status));
1176        goto GetPrs;
1177    }
1178
1179
1180    /* _PRS */
1181
1182GetPrs:
1183    AcpiOsPrintf ("Evaluating _PRS\n");
1184
1185    ReturnObj.Pointer           = AcpiGbl_DbBuffer;
1186    ReturnObj.Length            = ACPI_DEBUG_BUFFER_SIZE;
1187
1188    Status = AcpiEvaluateObject (ObjDesc, "_PRS", NULL, &ReturnObj);
1189    if (ACPI_FAILURE (Status))
1190    {
1191        AcpiOsPrintf ("Could not obtain _PRS: %s\n", AcpiFormatException (Status));
1192        goto Cleanup;
1193    }
1194
1195    ReturnObj.Pointer           = AcpiGbl_DbBuffer;
1196    ReturnObj.Length            = ACPI_DEBUG_BUFFER_SIZE;
1197
1198    Status = AcpiGetPossibleResources (ObjDesc, &ReturnObj);
1199    if (ACPI_FAILURE (Status))
1200    {
1201        AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", AcpiFormatException (Status));
1202    }
1203    else
1204    {
1205        AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1206    }
1207
1208Cleanup:
1209
1210    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1211    return;
1212#endif
1213}
1214
1215
1216/*******************************************************************************
1217 *
1218 * FUNCTION:    AcpiDbIntegrityWalk
1219 *
1220 * PARAMETERS:  Callback from WalkNamespace
1221 *
1222 * RETURN:      Status
1223 *
1224 * DESCRIPTION: Examine one NS node for valid values.
1225 *
1226 ******************************************************************************/
1227
1228ACPI_STATUS
1229AcpiDbIntegrityWalk (
1230    ACPI_HANDLE             ObjHandle,
1231    UINT32                  NestingLevel,
1232    void                    *Context,
1233    void                    **ReturnValue)
1234{
1235    ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1236    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1237    ACPI_OPERAND_OBJECT     *Object;
1238
1239
1240    Info->Nodes++;
1241    if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1242    {
1243        AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s]\n",
1244            Node, AcpiUtGetDescriptorName (Node));
1245    }
1246
1247    if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1248    {
1249        AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1250            Node, Node->Type);
1251    }
1252
1253    if (!AcpiUtValidAcpiName (Node->Name.Integer))
1254    {
1255        AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1256    }
1257
1258    Object = AcpiNsGetAttachedObject (Node);
1259    if (Object)
1260    {
1261        Info->Objects++;
1262        if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1263        {
1264            AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1265                Object, AcpiUtGetDescriptorName (Object));
1266        }
1267    }
1268
1269    return (AE_OK);
1270}
1271
1272
1273/*******************************************************************************
1274 *
1275 * FUNCTION:    AcpiDbCheckIntegrity
1276 *
1277 * PARAMETERS:  None
1278 *
1279 * RETURN:      None
1280 *
1281 * DESCRIPTION: Check entire namespace for data structure integrity
1282 *
1283 ******************************************************************************/
1284
1285void
1286AcpiDbCheckIntegrity (void)
1287{
1288    ACPI_INTEGRITY_INFO     Info = {0,0};
1289
1290    /* Search all nodes in namespace */
1291
1292    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1293                    AcpiDbIntegrityWalk, (void *) &Info, NULL);
1294
1295    AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n", Info.Nodes, Info.Objects);
1296}
1297
1298
1299/*******************************************************************************
1300 *
1301 * FUNCTION:    AcpiDbGenerateGpe
1302 *
1303 * PARAMETERS:  None
1304 *
1305 * RETURN:      None
1306 *
1307 * DESCRIPTION: Generate a GPE
1308 *
1309 ******************************************************************************/
1310
1311void
1312AcpiDbGenerateGpe (
1313    char                    *GpeArg,
1314    char                    *BlockArg)
1315{
1316    UINT32                  BlockNumber;
1317    UINT32                  GpeNumber;
1318    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1319
1320
1321    GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1322    BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1323
1324
1325    GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber), GpeNumber);
1326    if (!GpeEventInfo)
1327    {
1328        AcpiOsPrintf ("Invalid GPE\n");
1329        return;
1330    }
1331
1332    (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1333}
1334
1335#endif /* ACPI_DEBUGGER */
1336