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