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