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