Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 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 "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
 
134
/* Local prototypes */
135
 
136
static ACPI_STATUS
137
AcpiDbIntegrityWalk (
138
    ACPI_HANDLE             ObjHandle,
139
    UINT32                  NestingLevel,
140
    void                    *Context,
141
    void                    **ReturnValue);
142
 
143
static ACPI_STATUS
144
AcpiDbWalkAndMatchName (
145
    ACPI_HANDLE             ObjHandle,
146
    UINT32                  NestingLevel,
147
    void                    *Context,
148
    void                    **ReturnValue);
149
 
150
static ACPI_STATUS
151
AcpiDbWalkForReferences (
152
    ACPI_HANDLE             ObjHandle,
153
    UINT32                  NestingLevel,
154
    void                    *Context,
155
    void                    **ReturnValue);
156
 
157
static ACPI_STATUS
158
AcpiDbWalkForSpecificObjects (
159
    ACPI_HANDLE             ObjHandle,
160
    UINT32                  NestingLevel,
161
    void                    *Context,
162
    void                    **ReturnValue);
163
 
164
static ACPI_NAMESPACE_NODE *
165
AcpiDbConvertToNode (
166
    char                    *InString);
167
 
168
static void
169
AcpiDmCompareAmlResources (
170
    UINT8                   *Aml1Buffer,
171
    ACPI_RSDESC_SIZE        Aml1BufferLength,
172
    UINT8                   *Aml2Buffer,
173
    ACPI_RSDESC_SIZE        Aml2BufferLength);
174
 
175
static ACPI_STATUS
176
AcpiDmTestResourceConversion (
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
 */
185
static 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
 
226
static ACPI_NAMESPACE_NODE *
227
AcpiDbConvertToNode (
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
 
283
ACPI_STATUS
284
AcpiDbSleep (
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
 
329
static ACPI_STATUS
330
AcpiDbWalkForReferences (
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
 
372
void
373
AcpiDbFindReferences (
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
 
403
static ACPI_STATUS
404
AcpiDbWalkForPredefinedNames (
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
 
468
void
469
AcpiDbCheckPredefinedNames (
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
 
497
static ACPI_STATUS
498
AcpiDbWalkForExecute (
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
 
601
void
602
AcpiDbBatchExecute (
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
 
638
void
639
AcpiDbDisplayLocks (
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
 
667
void
668
AcpiDbDisplayTableInfo (
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
 
723
void
724
AcpiDbUnloadAcpiTable (
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
 
779
void
780
AcpiDbSetMethodBreakpoint (
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
 
823
void
824
AcpiDbSetMethodCallBreakpoint (
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
 
853
void
854
AcpiDbDisassembleAml (
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
    AcpiDmDisassemble (NULL, Op, NumStatements);
873
}
874
 
875
 
876
/*******************************************************************************
877
 *
878
 * FUNCTION:    AcpiDbDisassembleMethod
879
 *
880
 * PARAMETERS:  Name            - Name of control method
881
 *
882
 * RETURN:      None
883
 *
884
 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
885
 *              of statements specified.
886
 *
887
 ******************************************************************************/
888
 
889
ACPI_STATUS
890
AcpiDbDisassembleMethod (
891
    char                    *Name)
892
{
893
    ACPI_STATUS             Status;
894
    ACPI_PARSE_OBJECT       *Op;
895
    ACPI_WALK_STATE         *WalkState;
896
    ACPI_OPERAND_OBJECT     *ObjDesc;
897
    ACPI_NAMESPACE_NODE     *Method;
898
 
899
 
900
    Method = AcpiDbConvertToNode (Name);
901
    if (!Method)
902
    {
903
        return (AE_BAD_PARAMETER);
904
    }
905
 
906
    ObjDesc = Method->Object;
907
 
908
    Op = AcpiPsCreateScopeOp ();
909
    if (!Op)
910
    {
911
        return (AE_NO_MEMORY);
912
    }
913
 
914
    /* Create and initialize a new walk state */
915
 
916
    WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
917
    if (!WalkState)
918
    {
919
        return (AE_NO_MEMORY);
920
    }
921
 
922
    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
923
                    ObjDesc->Method.AmlStart,
924
                    ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
925
    if (ACPI_FAILURE (Status))
926
    {
927
        return (Status);
928
    }
929
 
930
    /* Parse the AML */
931
 
932
    WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
933
    WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
934
    Status = AcpiPsParseAml (WalkState);
935
 
936
    AcpiDmDisassemble (NULL, Op, 0);
937
    AcpiPsDeleteParseTree (Op);
938
    return (AE_OK);
939
}
940
 
941
 
942
/*******************************************************************************
943
 *
944
 * FUNCTION:    AcpiDbDumpNamespace
945
 *
946
 * PARAMETERS:  StartArg        - Node to begin namespace dump
947
 *              DepthArg        - Maximum tree depth to be dumped
948
 *
949
 * RETURN:      None
950
 *
951
 * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
952
 *              with type and other information.
953
 *
954
 ******************************************************************************/
955
 
956
void
957
AcpiDbDumpNamespace (
958
    char                    *StartArg,
959
    char                    *DepthArg)
960
{
961
    ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
962
    UINT32                  MaxDepth = ACPI_UINT32_MAX;
963
 
964
 
965
    /* No argument given, just start at the root and dump entire namespace */
966
 
967
    if (StartArg)
968
    {
969
        SubtreeEntry = AcpiDbConvertToNode (StartArg);
970
        if (!SubtreeEntry)
971
        {
972
            return;
973
        }
974
 
975
        /* Now we can check for the depth argument */
976
 
977
        if (DepthArg)
978
        {
979
            MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
980
        }
981
    }
982
 
983
    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
984
    AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
985
        ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
986
 
987
    /* Display the subtree */
988
 
989
    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
990
    AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
991
        ACPI_OWNER_ID_MAX, SubtreeEntry);
992
    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
993
}
994
 
995
 
996
/*******************************************************************************
997
 *
998
 * FUNCTION:    AcpiDbDumpNamespaceByOwner
999
 *
1000
 * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
1001
 *              DepthArg        - Maximum tree depth to be dumped
1002
 *
1003
 * RETURN:      None
1004
 *
1005
 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
1006
 *
1007
 ******************************************************************************/
1008
 
1009
void
1010
AcpiDbDumpNamespaceByOwner (
1011
    char                    *OwnerArg,
1012
    char                    *DepthArg)
1013
{
1014
    ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
1015
    UINT32                  MaxDepth = ACPI_UINT32_MAX;
1016
    ACPI_OWNER_ID           OwnerId;
1017
 
1018
 
1019
    OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
1020
 
1021
    /* Now we can check for the depth argument */
1022
 
1023
    if (DepthArg)
1024
    {
1025
        MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
1026
    }
1027
 
1028
    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1029
    AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
1030
 
1031
    /* Display the subtree */
1032
 
1033
    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1034
    AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
1035
        SubtreeEntry);
1036
    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1037
}
1038
 
1039
 
1040
/*******************************************************************************
1041
 *
1042
 * FUNCTION:    AcpiDbSendNotify
1043
 *
1044
 * PARAMETERS:  Name            - Name of ACPI object to send the notify to
1045
 *              Value           - Value of the notify to send.
1046
 *
1047
 * RETURN:      None
1048
 *
1049
 * DESCRIPTION: Send an ACPI notification.  The value specified is sent to the
1050
 *              named object as an ACPI notify.
1051
 *
1052
 ******************************************************************************/
1053
 
1054
void
1055
AcpiDbSendNotify (
1056
    char                    *Name,
1057
    UINT32                  Value)
1058
{
1059
    ACPI_NAMESPACE_NODE     *Node;
1060
    ACPI_STATUS             Status;
1061
 
1062
 
1063
    /* Translate name to an Named object */
1064
 
1065
    Node = AcpiDbConvertToNode (Name);
1066
    if (!Node)
1067
    {
1068
        return;
1069
    }
1070
 
1071
    /* Decode Named object type */
1072
 
1073
    switch (Node->Type)
1074
    {
1075
    case ACPI_TYPE_DEVICE:
1076
    case ACPI_TYPE_THERMAL:
1077
 
1078
         /* Send the notify */
1079
 
1080
        Status = AcpiEvQueueNotifyRequest (Node, Value);
1081
        if (ACPI_FAILURE (Status))
1082
        {
1083
            AcpiOsPrintf ("Could not queue notify\n");
1084
        }
1085
        break;
1086
 
1087
    default:
1088
        AcpiOsPrintf ("Named object is not a device or a thermal object\n");
1089
        break;
1090
    }
1091
}
1092
 
1093
 
1094
/*******************************************************************************
1095
 *
1096
 * FUNCTION:    AcpiDbSetMethodData
1097
 *
1098
 * PARAMETERS:  TypeArg         - L for local, A for argument
1099
 *              IndexArg        - which one
1100
 *              ValueArg        - Value to set.
1101
 *
1102
 * RETURN:      None
1103
 *
1104
 * DESCRIPTION: Set a local or argument for the running control method.
1105
 *              NOTE: only object supported is Number.
1106
 *
1107
 ******************************************************************************/
1108
 
1109
void
1110
AcpiDbSetMethodData (
1111
    char                    *TypeArg,
1112
    char                    *IndexArg,
1113
    char                    *ValueArg)
1114
{
1115
    char                    Type;
1116
    UINT32                  Index;
1117
    UINT32                  Value;
1118
    ACPI_WALK_STATE         *WalkState;
1119
    ACPI_OPERAND_OBJECT     *ObjDesc;
1120
    ACPI_STATUS             Status;
1121
    ACPI_NAMESPACE_NODE     *Node;
1122
 
1123
 
1124
    /* Validate TypeArg */
1125
 
1126
    AcpiUtStrupr (TypeArg);
1127
    Type = TypeArg[0];
1128
    if ((Type != 'L') &&
1129
        (Type != 'A') &&
1130
        (Type != 'N'))
1131
    {
1132
        AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
1133
        return;
1134
    }
1135
 
1136
    Value = ACPI_STRTOUL (ValueArg, NULL, 16);
1137
 
1138
    if (Type == 'N')
1139
    {
1140
        Node = AcpiDbConvertToNode (IndexArg);
1141
        if (Node->Type != ACPI_TYPE_INTEGER)
1142
        {
1143
            AcpiOsPrintf ("Can only set Integer nodes\n");
1144
            return;
1145
        }
1146
        ObjDesc = Node->Object;
1147
        ObjDesc->Integer.Value = Value;
1148
        return;
1149
    }
1150
 
1151
    /* Get the index and value */
1152
 
1153
    Index = ACPI_STRTOUL (IndexArg, NULL, 16);
1154
 
1155
    WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
1156
    if (!WalkState)
1157
    {
1158
        AcpiOsPrintf ("There is no method currently executing\n");
1159
        return;
1160
    }
1161
 
1162
    /* Create and initialize the new object */
1163
 
1164
    ObjDesc = AcpiUtCreateIntegerObject ((UINT64) Value);
1165
    if (!ObjDesc)
1166
    {
1167
        AcpiOsPrintf ("Could not create an internal object\n");
1168
        return;
1169
    }
1170
 
1171
    /* Store the new object into the target */
1172
 
1173
    switch (Type)
1174
    {
1175
    case 'A':
1176
 
1177
        /* Set a method argument */
1178
 
1179
        if (Index > ACPI_METHOD_MAX_ARG)
1180
        {
1181
            AcpiOsPrintf ("Arg%u - Invalid argument name\n", Index);
1182
            goto Cleanup;
1183
        }
1184
 
1185
        Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc,
1186
                    WalkState);
1187
        if (ACPI_FAILURE (Status))
1188
        {
1189
            goto Cleanup;
1190
        }
1191
 
1192
        ObjDesc = WalkState->Arguments[Index].Object;
1193
 
1194
        AcpiOsPrintf ("Arg%u: ", Index);
1195
        AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1196
        break;
1197
 
1198
    case 'L':
1199
 
1200
        /* Set a method local */
1201
 
1202
        if (Index > ACPI_METHOD_MAX_LOCAL)
1203
        {
1204
            AcpiOsPrintf ("Local%u - Invalid local variable name\n", Index);
1205
            goto Cleanup;
1206
        }
1207
 
1208
        Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc,
1209
                    WalkState);
1210
        if (ACPI_FAILURE (Status))
1211
        {
1212
            goto Cleanup;
1213
        }
1214
 
1215
        ObjDesc = WalkState->LocalVariables[Index].Object;
1216
 
1217
        AcpiOsPrintf ("Local%u: ", Index);
1218
        AcpiDmDisplayInternalObject (ObjDesc, WalkState);
1219
        break;
1220
 
1221
    default:
1222
        break;
1223
    }
1224
 
1225
Cleanup:
1226
    AcpiUtRemoveReference (ObjDesc);
1227
}
1228
 
1229
 
1230
/*******************************************************************************
1231
 *
1232
 * FUNCTION:    AcpiDbWalkForSpecificObjects
1233
 *
1234
 * PARAMETERS:  Callback from WalkNamespace
1235
 *
1236
 * RETURN:      Status
1237
 *
1238
 * DESCRIPTION: Display short info about objects in the namespace
1239
 *
1240
 ******************************************************************************/
1241
 
1242
static ACPI_STATUS
1243
AcpiDbWalkForSpecificObjects (
1244
    ACPI_HANDLE             ObjHandle,
1245
    UINT32                  NestingLevel,
1246
    void                    *Context,
1247
    void                    **ReturnValue)
1248
{
1249
    ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
1250
    ACPI_BUFFER             Buffer;
1251
    ACPI_STATUS             Status;
1252
 
1253
 
1254
    Info->Count++;
1255
 
1256
    /* Get and display the full pathname to this object */
1257
 
1258
    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1259
    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1260
    if (ACPI_FAILURE (Status))
1261
    {
1262
        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1263
        return (AE_OK);
1264
    }
1265
 
1266
    AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1267
    ACPI_FREE (Buffer.Pointer);
1268
 
1269
    /* Dump short info about the object */
1270
 
1271
    (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
1272
    return (AE_OK);
1273
}
1274
 
1275
 
1276
/*******************************************************************************
1277
 *
1278
 * FUNCTION:    AcpiDbDisplayObjects
1279
 *
1280
 * PARAMETERS:  ObjTypeArg          - Type of object to display
1281
 *              DisplayCountArg     - Max depth to display
1282
 *
1283
 * RETURN:      None
1284
 *
1285
 * DESCRIPTION: Display objects in the namespace of the requested type
1286
 *
1287
 ******************************************************************************/
1288
 
1289
ACPI_STATUS
1290
AcpiDbDisplayObjects (
1291
    char                    *ObjTypeArg,
1292
    char                    *DisplayCountArg)
1293
{
1294
    ACPI_WALK_INFO          Info;
1295
    ACPI_OBJECT_TYPE        Type;
1296
 
1297
 
1298
    /* Get the object type */
1299
 
1300
    Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
1301
    if (Type == ACPI_TYPE_NOT_FOUND)
1302
    {
1303
        AcpiOsPrintf ("Invalid or unsupported argument\n");
1304
        return (AE_OK);
1305
    }
1306
 
1307
    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
1308
    AcpiOsPrintf (
1309
        "Objects of type [%s] defined in the current ACPI Namespace:\n",
1310
        AcpiUtGetTypeName (Type));
1311
 
1312
    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1313
 
1314
    Info.Count = 0;
1315
    Info.OwnerId = ACPI_OWNER_ID_MAX;
1316
    Info.DebugLevel = ACPI_UINT32_MAX;
1317
    Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1318
 
1319
    /* Walk the namespace from the root */
1320
 
1321
    (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1322
                AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
1323
 
1324
    AcpiOsPrintf (
1325
        "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
1326
        Info.Count, AcpiUtGetTypeName (Type));
1327
 
1328
    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1329
    return (AE_OK);
1330
}
1331
 
1332
 
1333
/*******************************************************************************
1334
 *
1335
 * FUNCTION:    AcpiDbWalkAndMatchName
1336
 *
1337
 * PARAMETERS:  Callback from WalkNamespace
1338
 *
1339
 * RETURN:      Status
1340
 *
1341
 * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
1342
 *              are supported -- '?' matches any character.
1343
 *
1344
 ******************************************************************************/
1345
 
1346
static ACPI_STATUS
1347
AcpiDbWalkAndMatchName (
1348
    ACPI_HANDLE             ObjHandle,
1349
    UINT32                  NestingLevel,
1350
    void                    *Context,
1351
    void                    **ReturnValue)
1352
{
1353
    ACPI_STATUS             Status;
1354
    char                    *RequestedName = (char *) Context;
1355
    UINT32                  i;
1356
    ACPI_BUFFER             Buffer;
1357
    ACPI_WALK_INFO          Info;
1358
 
1359
 
1360
    /* Check for a name match */
1361
 
1362
    for (i = 0; i < 4; i++)
1363
    {
1364
        /* Wildcard support */
1365
 
1366
        if ((RequestedName[i] != '?') &&
1367
            (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
1368
        {
1369
            /* No match, just exit */
1370
 
1371
            return (AE_OK);
1372
        }
1373
    }
1374
 
1375
    /* Get the full pathname to this object */
1376
 
1377
    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1378
    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
1379
    if (ACPI_FAILURE (Status))
1380
    {
1381
        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
1382
    }
1383
    else
1384
    {
1385
        Info.OwnerId = ACPI_OWNER_ID_MAX;
1386
        Info.DebugLevel = ACPI_UINT32_MAX;
1387
        Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
1388
 
1389
        AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
1390
        (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
1391
        ACPI_FREE (Buffer.Pointer);
1392
    }
1393
 
1394
    return (AE_OK);
1395
}
1396
 
1397
 
1398
/*******************************************************************************
1399
 *
1400
 * FUNCTION:    AcpiDbFindNameInNamespace
1401
 *
1402
 * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
1403
 *                                wildcards are supported.
1404
 *
1405
 * RETURN:      None
1406
 *
1407
 * DESCRIPTION: Search the namespace for a given name (with wildcards)
1408
 *
1409
 ******************************************************************************/
1410
 
1411
ACPI_STATUS
1412
AcpiDbFindNameInNamespace (
1413
    char                    *NameArg)
1414
{
1415
    char                    AcpiName[5] = "____";
1416
    char                    *AcpiNamePtr = AcpiName;
1417
 
1418
 
1419
    if (ACPI_STRLEN (NameArg) > 4)
1420
    {
1421
        AcpiOsPrintf ("Name must be no longer than 4 characters\n");
1422
        return (AE_OK);
1423
    }
1424
 
1425
    /* Pad out name with underscores as necessary to create a 4-char name */
1426
 
1427
    AcpiUtStrupr (NameArg);
1428
    while (*NameArg)
1429
    {
1430
        *AcpiNamePtr = *NameArg;
1431
        AcpiNamePtr++;
1432
        NameArg++;
1433
    }
1434
 
1435
    /* Walk the namespace from the root */
1436
 
1437
    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1438
                        AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
1439
 
1440
    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1441
    return (AE_OK);
1442
}
1443
 
1444
 
1445
/*******************************************************************************
1446
 *
1447
 * FUNCTION:    AcpiDbSetScope
1448
 *
1449
 * PARAMETERS:  Name                - New scope path
1450
 *
1451
 * RETURN:      Status
1452
 *
1453
 * DESCRIPTION: Set the "current scope" as maintained by this utility.
1454
 *              The scope is used as a prefix to ACPI paths.
1455
 *
1456
 ******************************************************************************/
1457
 
1458
void
1459
AcpiDbSetScope (
1460
    char                    *Name)
1461
{
1462
    ACPI_STATUS             Status;
1463
    ACPI_NAMESPACE_NODE     *Node;
1464
 
1465
 
1466
    if (!Name || Name[0] == 0)
1467
    {
1468
        AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
1469
        return;
1470
    }
1471
 
1472
    AcpiDbPrepNamestring (Name);
1473
 
1474
    if (Name[0] == '\\')
1475
    {
1476
        /* Validate new scope from the root */
1477
 
1478
        Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
1479
                    &Node);
1480
        if (ACPI_FAILURE (Status))
1481
        {
1482
            goto ErrorExit;
1483
        }
1484
 
1485
        ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
1486
        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1487
    }
1488
    else
1489
    {
1490
        /* Validate new scope relative to old scope */
1491
 
1492
        Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
1493
                    &Node);
1494
        if (ACPI_FAILURE (Status))
1495
        {
1496
            goto ErrorExit;
1497
        }
1498
 
1499
        ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
1500
        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
1501
    }
1502
 
1503
    AcpiGbl_DbScopeNode = Node;
1504
    AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
1505
    return;
1506
 
1507
ErrorExit:
1508
 
1509
    AcpiOsPrintf ("Could not attach scope: %s, %s\n",
1510
        Name, AcpiFormatException (Status));
1511
}
1512
 
1513
 
1514
/*******************************************************************************
1515
 *
1516
 * FUNCTION:    AcpiDmCompareAmlResources
1517
 *
1518
 * PARAMETERS:  Aml1Buffer          - Contains first resource list
1519
 *              Aml1BufferLength    - Length of first resource list
1520
 *              Aml2Buffer          - Contains second resource list
1521
 *              Aml2BufferLength    - Length of second resource list
1522
 *
1523
 * RETURN:      None
1524
 *
1525
 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
1526
 *              order to isolate a miscompare to an individual resource)
1527
 *
1528
 ******************************************************************************/
1529
 
1530
static void
1531
AcpiDmCompareAmlResources (
1532
    UINT8                   *Aml1Buffer,
1533
    ACPI_RSDESC_SIZE        Aml1BufferLength,
1534
    UINT8                   *Aml2Buffer,
1535
    ACPI_RSDESC_SIZE        Aml2BufferLength)
1536
{
1537
    UINT8                   *Aml1;
1538
    UINT8                   *Aml2;
1539
    ACPI_RSDESC_SIZE        Aml1Length;
1540
    ACPI_RSDESC_SIZE        Aml2Length;
1541
    ACPI_RSDESC_SIZE        Offset = 0;
1542
    UINT8                   ResourceType;
1543
    UINT32                  Count = 0;
1544
 
1545
 
1546
    /* Compare overall buffer sizes (may be different due to size rounding) */
1547
 
1548
    if (Aml1BufferLength != Aml2BufferLength)
1549
    {
1550
        AcpiOsPrintf (
1551
            "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
1552
            Aml1BufferLength, Aml2BufferLength);
1553
    }
1554
 
1555
    Aml1 = Aml1Buffer;
1556
    Aml2 = Aml2Buffer;
1557
 
1558
    /* Walk the descriptor lists, comparing each descriptor */
1559
 
1560
    while (Aml1 < (Aml1Buffer + Aml1BufferLength))
1561
    {
1562
        /* Get the lengths of each descriptor */
1563
 
1564
        Aml1Length = AcpiUtGetDescriptorLength (Aml1);
1565
        Aml2Length = AcpiUtGetDescriptorLength (Aml2);
1566
        ResourceType = AcpiUtGetResourceType (Aml1);
1567
 
1568
        /* Check for descriptor length match */
1569
 
1570
        if (Aml1Length != Aml2Length)
1571
        {
1572
            AcpiOsPrintf (
1573
                "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
1574
                Count, ResourceType, Offset, Aml1Length, Aml2Length);
1575
        }
1576
 
1577
        /* Check for descriptor byte match */
1578
 
1579
        else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
1580
        {
1581
            AcpiOsPrintf (
1582
                "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
1583
                Count, ResourceType, Offset);
1584
        }
1585
 
1586
        /* Exit on EndTag descriptor */
1587
 
1588
        if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
1589
        {
1590
            return;
1591
        }
1592
 
1593
        /* Point to next descriptor in each buffer */
1594
 
1595
        Count++;
1596
        Offset += Aml1Length;
1597
        Aml1 += Aml1Length;
1598
        Aml2 += Aml2Length;
1599
    }
1600
}
1601
 
1602
 
1603
/*******************************************************************************
1604
 *
1605
 * FUNCTION:    AcpiDmTestResourceConversion
1606
 *
1607
 * PARAMETERS:  Node            - Parent device node
1608
 *              Name            - resource method name (_CRS)
1609
 *
1610
 * RETURN:      Status
1611
 *
1612
 * DESCRIPTION: Compare the original AML with a conversion of the AML to
1613
 *              internal resource list, then back to AML.
1614
 *
1615
 ******************************************************************************/
1616
 
1617
static ACPI_STATUS
1618
AcpiDmTestResourceConversion (
1619
    ACPI_NAMESPACE_NODE     *Node,
1620
    char                    *Name)
1621
{
1622
    ACPI_STATUS             Status;
1623
    ACPI_BUFFER             ReturnObj;
1624
    ACPI_BUFFER             ResourceObj;
1625
    ACPI_BUFFER             NewAml;
1626
    ACPI_OBJECT             *OriginalAml;
1627
 
1628
 
1629
    AcpiOsPrintf ("Resource Conversion Comparison:\n");
1630
 
1631
    NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1632
    ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1633
    ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1634
 
1635
    /* Get the original _CRS AML resource template */
1636
 
1637
    Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
1638
    if (ACPI_FAILURE (Status))
1639
    {
1640
        AcpiOsPrintf ("Could not obtain %s: %s\n",
1641
            Name, AcpiFormatException (Status));
1642
        return (Status);
1643
    }
1644
 
1645
    /* Get the AML resource template, converted to internal resource structs */
1646
 
1647
    Status = AcpiGetCurrentResources (Node, &ResourceObj);
1648
    if (ACPI_FAILURE (Status))
1649
    {
1650
        AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1651
            AcpiFormatException (Status));
1652
        goto Exit1;
1653
    }
1654
 
1655
    /* Convert internal resource list to external AML resource template */
1656
 
1657
    Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
1658
    if (ACPI_FAILURE (Status))
1659
    {
1660
        AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
1661
            AcpiFormatException (Status));
1662
        goto Exit2;
1663
    }
1664
 
1665
    /* Compare original AML to the newly created AML resource list */
1666
 
1667
    OriginalAml = ReturnObj.Pointer;
1668
 
1669
    AcpiDmCompareAmlResources (
1670
        OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
1671
        NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
1672
 
1673
    /* Cleanup and exit */
1674
 
1675
    ACPI_FREE (NewAml.Pointer);
1676
Exit2:
1677
    ACPI_FREE (ResourceObj.Pointer);
1678
Exit1:
1679
    ACPI_FREE (ReturnObj.Pointer);
1680
    return (Status);
1681
}
1682
 
1683
 
1684
/*******************************************************************************
1685
 *
1686
 * FUNCTION:    AcpiDbDisplayResources
1687
 *
1688
 * PARAMETERS:  ObjectArg       - String with hex value of the object
1689
 *
1690
 * RETURN:      None
1691
 *
1692
 * DESCRIPTION: Display the resource objects associated with a device.
1693
 *
1694
 ******************************************************************************/
1695
 
1696
void
1697
AcpiDbDisplayResources (
1698
    char                    *ObjectArg)
1699
{
1700
    ACPI_NAMESPACE_NODE     *Node;
1701
    ACPI_STATUS             Status;
1702
    ACPI_BUFFER             ReturnObj;
1703
 
1704
 
1705
    AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
1706
    AcpiDbgLevel |= ACPI_LV_RESOURCES;
1707
 
1708
    /* Convert string to object pointer */
1709
 
1710
    Node = AcpiDbConvertToNode (ObjectArg);
1711
    if (!Node)
1712
    {
1713
        return;
1714
    }
1715
 
1716
    /* Prepare for a return object of arbitrary size */
1717
 
1718
    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1719
    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1720
 
1721
    /* _PRT */
1722
 
1723
    AcpiOsPrintf ("Evaluating _PRT\n");
1724
 
1725
    /* Check if _PRT exists */
1726
 
1727
    Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
1728
    if (ACPI_FAILURE (Status))
1729
    {
1730
        AcpiOsPrintf ("Could not obtain _PRT: %s\n",
1731
            AcpiFormatException (Status));
1732
        goto GetCrs;
1733
    }
1734
 
1735
    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1736
    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1737
 
1738
    Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
1739
    if (ACPI_FAILURE (Status))
1740
    {
1741
        AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
1742
            AcpiFormatException (Status));
1743
        goto GetCrs;
1744
    }
1745
 
1746
    AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
1747
 
1748
 
1749
    /* _CRS */
1750
 
1751
GetCrs:
1752
    AcpiOsPrintf ("Evaluating _CRS\n");
1753
 
1754
    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1755
    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1756
 
1757
    /* Check if _CRS exists */
1758
 
1759
    Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
1760
    if (ACPI_FAILURE (Status))
1761
    {
1762
        AcpiOsPrintf ("Could not obtain _CRS: %s\n",
1763
            AcpiFormatException (Status));
1764
        goto GetPrs;
1765
    }
1766
 
1767
    /* Get the _CRS resource list */
1768
 
1769
    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1770
    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1771
 
1772
    Status = AcpiGetCurrentResources (Node, &ReturnObj);
1773
    if (ACPI_FAILURE (Status))
1774
    {
1775
        AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
1776
            AcpiFormatException (Status));
1777
        goto GetPrs;
1778
    }
1779
 
1780
    /* Dump the _CRS resource list */
1781
 
1782
    AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
1783
        ReturnObj.Pointer));
1784
 
1785
    /*
1786
     * Perform comparison of original AML to newly created AML. This tests both
1787
     * the AML->Resource conversion and the Resource->Aml conversion.
1788
     */
1789
    Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
1790
 
1791
    /* Execute _SRS with the resource list */
1792
 
1793
    Status = AcpiSetCurrentResources (Node, &ReturnObj);
1794
    if (ACPI_FAILURE (Status))
1795
    {
1796
        AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
1797
            AcpiFormatException (Status));
1798
        goto GetPrs;
1799
    }
1800
 
1801
 
1802
    /* _PRS */
1803
 
1804
GetPrs:
1805
    AcpiOsPrintf ("Evaluating _PRS\n");
1806
 
1807
    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1808
    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1809
 
1810
    /* Check if _PRS exists */
1811
 
1812
    Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
1813
    if (ACPI_FAILURE (Status))
1814
    {
1815
        AcpiOsPrintf ("Could not obtain _PRS: %s\n",
1816
            AcpiFormatException (Status));
1817
        goto Cleanup;
1818
    }
1819
 
1820
    ReturnObj.Pointer = AcpiGbl_DbBuffer;
1821
    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;
1822
 
1823
    Status = AcpiGetPossibleResources (Node, &ReturnObj);
1824
    if (ACPI_FAILURE (Status))
1825
    {
1826
        AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
1827
            AcpiFormatException (Status));
1828
        goto Cleanup;
1829
    }
1830
 
1831
    AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
1832
 
1833
Cleanup:
1834
 
1835
    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
1836
    return;
1837
}
1838
 
1839
 
1840
/*******************************************************************************
1841
 *
1842
 * FUNCTION:    AcpiDbIntegrityWalk
1843
 *
1844
 * PARAMETERS:  Callback from WalkNamespace
1845
 *
1846
 * RETURN:      Status
1847
 *
1848
 * DESCRIPTION: Examine one NS node for valid values.
1849
 *
1850
 ******************************************************************************/
1851
 
1852
static ACPI_STATUS
1853
AcpiDbIntegrityWalk (
1854
    ACPI_HANDLE             ObjHandle,
1855
    UINT32                  NestingLevel,
1856
    void                    *Context,
1857
    void                    **ReturnValue)
1858
{
1859
    ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
1860
    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1861
    ACPI_OPERAND_OBJECT     *Object;
1862
    BOOLEAN                 Alias = TRUE;
1863
 
1864
 
1865
    Info->Nodes++;
1866
 
1867
    /* Verify the NS node, and dereference aliases */
1868
 
1869
    while (Alias)
1870
    {
1871
        if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
1872
        {
1873
            AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
1874
                Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
1875
                ACPI_DESC_TYPE_NAMED);
1876
            return (AE_OK);
1877
        }
1878
 
1879
        if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
1880
            (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
1881
        {
1882
            Node = (ACPI_NAMESPACE_NODE *) Node->Object;
1883
        }
1884
        else
1885
        {
1886
            Alias = FALSE;
1887
        }
1888
    }
1889
 
1890
    if (Node->Type > ACPI_TYPE_LOCAL_MAX)
1891
    {
1892
        AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
1893
            Node, Node->Type);
1894
        return (AE_OK);
1895
    }
1896
 
1897
    if (!AcpiUtValidAcpiName (Node->Name.Integer))
1898
    {
1899
        AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
1900
        return (AE_OK);
1901
    }
1902
 
1903
    Object = AcpiNsGetAttachedObject (Node);
1904
    if (Object)
1905
    {
1906
        Info->Objects++;
1907
        if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
1908
        {
1909
            AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
1910
                Object, AcpiUtGetDescriptorName (Object));
1911
        }
1912
    }
1913
 
1914
    return (AE_OK);
1915
}
1916
 
1917
 
1918
/*******************************************************************************
1919
 *
1920
 * FUNCTION:    AcpiDbCheckIntegrity
1921
 *
1922
 * PARAMETERS:  None
1923
 *
1924
 * RETURN:      None
1925
 *
1926
 * DESCRIPTION: Check entire namespace for data structure integrity
1927
 *
1928
 ******************************************************************************/
1929
 
1930
void
1931
AcpiDbCheckIntegrity (
1932
    void)
1933
{
1934
    ACPI_INTEGRITY_INFO     Info = {0,0};
1935
 
1936
    /* Search all nodes in namespace */
1937
 
1938
    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
1939
                    AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
1940
 
1941
    AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
1942
        Info.Nodes, Info.Objects);
1943
}
1944
 
1945
 
1946
/*******************************************************************************
1947
 *
1948
 * FUNCTION:    AcpiDbGenerateGpe
1949
 *
1950
 * PARAMETERS:  GpeArg          - Raw GPE number, ascii string
1951
 *              BlockArg        - GPE block number, ascii string
1952
 *                                0 or 1 for FADT GPE blocks
1953
 *
1954
 * RETURN:      None
1955
 *
1956
 * DESCRIPTION: Generate a GPE
1957
 *
1958
 ******************************************************************************/
1959
 
1960
void
1961
AcpiDbGenerateGpe (
1962
    char                    *GpeArg,
1963
    char                    *BlockArg)
1964
{
1965
    UINT32                  BlockNumber;
1966
    UINT32                  GpeNumber;
1967
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
1968
 
1969
 
1970
    GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
1971
    BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
1972
 
1973
 
1974
    GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
1975
        GpeNumber);
1976
    if (!GpeEventInfo)
1977
    {
1978
        AcpiOsPrintf ("Invalid GPE\n");
1979
        return;
1980
    }
1981
 
1982
    (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
1983
}
1984
 
1985
 
1986
/*******************************************************************************
1987
 *
1988
 * FUNCTION:    AcpiDbBusWalk
1989
 *
1990
 * PARAMETERS:  Callback from WalkNamespace
1991
 *
1992
 * RETURN:      Status
1993
 *
1994
 * DESCRIPTION: Display info about device objects that have a corresponding
1995
 *              _PRT method.
1996
 *
1997
 ******************************************************************************/
1998
 
1999
static ACPI_STATUS
2000
AcpiDbBusWalk (
2001
    ACPI_HANDLE             ObjHandle,
2002
    UINT32                  NestingLevel,
2003
    void                    *Context,
2004
    void                    **ReturnValue)
2005
{
2006
    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
2007
    ACPI_STATUS             Status;
2008
    ACPI_BUFFER             Buffer;
2009
    ACPI_NAMESPACE_NODE     *TempNode;
2010
    ACPI_DEVICE_INFO        *Info;
2011
    UINT32                  i;
2012
 
2013
 
2014
    if ((Node->Type != ACPI_TYPE_DEVICE) &&
2015
        (Node->Type != ACPI_TYPE_PROCESSOR))
2016
    {
2017
        return (AE_OK);
2018
    }
2019
 
2020
    /* Exit if there is no _PRT under this device */
2021
 
2022
    Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
2023
                ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
2024
    if (ACPI_FAILURE (Status))
2025
    {
2026
        return (AE_OK);
2027
    }
2028
 
2029
    /* Get the full path to this device object */
2030
 
2031
    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
2032
    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
2033
    if (ACPI_FAILURE (Status))
2034
    {
2035
        AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
2036
        return (AE_OK);
2037
    }
2038
 
2039
    Status = AcpiGetObjectInfo (ObjHandle, &Info);
2040
    if (ACPI_FAILURE (Status))
2041
    {
2042
        return (AE_OK);
2043
    }
2044
 
2045
    /* Display the full path */
2046
 
2047
    AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
2048
    ACPI_FREE (Buffer.Pointer);
2049
 
2050
    if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
2051
    {
2052
        AcpiOsPrintf ("  - Is PCI Root Bridge");
2053
    }
2054
    AcpiOsPrintf ("\n");
2055
 
2056
    /* _PRT info */
2057
 
2058
    AcpiOsPrintf ("_PRT: %p\n", TempNode);
2059
 
2060
    /* Dump _ADR, _HID, _UID, _CID */
2061
 
2062
    if (Info->Valid & ACPI_VALID_ADR)
2063
    {
2064
        AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
2065
    }
2066
    else
2067
    {
2068
        AcpiOsPrintf ("_ADR: \n");
2069
    }
2070
 
2071
    if (Info->Valid & ACPI_VALID_HID)
2072
    {
2073
        AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
2074
    }
2075
    else
2076
    {
2077
        AcpiOsPrintf ("_HID: \n");
2078
    }
2079
 
2080
    if (Info->Valid & ACPI_VALID_UID)
2081
    {
2082
        AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
2083
    }
2084
    else
2085
    {
2086
        AcpiOsPrintf ("_UID: \n");
2087
    }
2088
 
2089
    if (Info->Valid & ACPI_VALID_CID)
2090
    {
2091
        for (i = 0; i < Info->CompatibleIdList.Count; i++)
2092
        {
2093
            AcpiOsPrintf ("_CID: %s\n",
2094
                Info->CompatibleIdList.Ids[i].String);
2095
        }
2096
    }
2097
    else
2098
    {
2099
        AcpiOsPrintf ("_CID: \n");
2100
    }
2101
 
2102
    ACPI_FREE (Info);
2103
    return (AE_OK);
2104
}
2105
 
2106
 
2107
/*******************************************************************************
2108
 *
2109
 * FUNCTION:    AcpiDbGetBusInfo
2110
 *
2111
 * PARAMETERS:  None
2112
 *
2113
 * RETURN:      None
2114
 *
2115
 * DESCRIPTION: Display info about system busses.
2116
 *
2117
 ******************************************************************************/
2118
 
2119
void
2120
AcpiDbGetBusInfo (
2121
    void)
2122
{
2123
    /* Search all nodes in namespace */
2124
 
2125
    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
2126
                    AcpiDbBusWalk, NULL, NULL, NULL);
2127
}
2128
 
2129
#endif /* ACPI_DEBUGGER */