Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/******************************************************************************
2
 *
3
 * Module Name: adisasm - Application-level disassembler routines
4
 *
5
 *****************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 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 "acparser.h"
120
#include "amlcode.h"
121
#include "acdebug.h"
122
#include "acdisasm.h"
123
#include "acdispat.h"
124
#include "acnamesp.h"
125
#include "actables.h"
126
#include "acapps.h"
127
 
128
#include 
129
#include 
130
 
131
 
132
#define _COMPONENT          ACPI_TOOLS
133
        ACPI_MODULE_NAME    ("adisasm")
134
 
135
 
136
extern int                  AslCompilerdebug;
137
 
138
 
139
ACPI_STATUS
140
LsDisplayNamespace (
141
    void);
142
 
143
void
144
LsSetupNsList (
145
    void                    *Handle);
146
 
147
 
148
/* Local prototypes */
149
 
2216 Serge 150
static void
1498 serge 151
AdCreateTableHeader (
152
    char                    *Filename,
153
    ACPI_TABLE_HEADER       *Table);
154
 
2216 Serge 155
static ACPI_STATUS
1498 serge 156
AdDeferredParse (
157
    ACPI_PARSE_OBJECT       *Op,
158
    UINT8                   *Aml,
159
    UINT32                  AmlLength);
160
 
2216 Serge 161
static ACPI_STATUS
1498 serge 162
AdParseDeferredOps (
163
    ACPI_PARSE_OBJECT       *Root);
164
 
165
 
166
/* Stubs for ASL compiler */
167
 
168
#ifndef ACPI_ASL_COMPILER
169
BOOLEAN
170
AcpiDsIsResultUsed (
171
    ACPI_PARSE_OBJECT       *Op,
172
    ACPI_WALK_STATE         *WalkState)
173
{
174
    return TRUE;
175
}
176
 
177
ACPI_STATUS
178
AcpiDsMethodError (
179
    ACPI_STATUS             Status,
180
    ACPI_WALK_STATE         *WalkState)
181
{
182
    return (Status);
183
}
184
#endif
185
 
186
ACPI_STATUS
187
AcpiNsLoadTable (
188
    UINT32                  TableIndex,
189
    ACPI_NAMESPACE_NODE     *Node)
190
{
191
    return (AE_NOT_IMPLEMENTED);
192
}
193
 
194
ACPI_STATUS
195
AcpiDsRestartControlMethod (
196
    ACPI_WALK_STATE         *WalkState,
197
    ACPI_OPERAND_OBJECT     *ReturnDesc)
198
{
199
    return (AE_OK);
200
}
201
 
202
void
203
AcpiDsTerminateControlMethod (
204
    ACPI_OPERAND_OBJECT     *MethodDesc,
205
    ACPI_WALK_STATE         *WalkState)
206
{
207
    return;
208
}
209
 
210
ACPI_STATUS
211
AcpiDsCallControlMethod (
212
    ACPI_THREAD_STATE       *Thread,
213
    ACPI_WALK_STATE         *WalkState,
214
    ACPI_PARSE_OBJECT       *Op)
215
{
216
    return (AE_OK);
217
}
218
 
219
ACPI_STATUS
220
AcpiDsMethodDataInitArgs (
221
    ACPI_OPERAND_OBJECT     **Params,
222
    UINT32                  MaxParamCount,
223
    ACPI_WALK_STATE         *WalkState)
224
{
225
    return (AE_OK);
226
}
227
 
228
 
229
static ACPI_TABLE_DESC      LocalTables[1];
230
static ACPI_PARSE_OBJECT    *AcpiGbl_ParseOpRoot;
231
 
232
 
233
/*******************************************************************************
234
 *
235
 * FUNCTION:    AdInitialize
236
 *
237
 * PARAMETERS:  None
238
 *
239
 * RETURN:      Status
240
 *
241
 * DESCRIPTION: ACPICA and local initialization
242
 *
243
 ******************************************************************************/
244
 
245
ACPI_STATUS
246
AdInitialize (
247
    void)
248
{
249
    ACPI_STATUS             Status;
250
 
251
 
252
    /* ACPI CA subsystem initialization */
253
 
254
    Status = AcpiOsInitialize ();
255
    if (ACPI_FAILURE (Status))
256
    {
257
        return (Status);
258
    }
259
 
260
    Status = AcpiUtInitGlobals ();
261
    if (ACPI_FAILURE (Status))
262
    {
263
        return (Status);
264
    }
265
 
266
    Status = AcpiUtMutexInitialize ();
267
    if (ACPI_FAILURE (Status))
268
    {
269
        return (Status);
270
    }
271
 
272
    Status = AcpiNsRootInitialize ();
273
    if (ACPI_FAILURE (Status))
274
    {
275
        return (Status);
276
    }
277
 
278
    /* Setup the Table Manager (cheat - there is no RSDT) */
279
 
280
    AcpiGbl_RootTableList.MaxTableCount = 1;
281
    AcpiGbl_RootTableList.CurrentTableCount = 0;
282
    AcpiGbl_RootTableList.Tables = LocalTables;
283
 
284
    return (Status);
285
}
286
 
287
 
288
/******************************************************************************
289
 *
290
 * FUNCTION:    AdAmlDisassemble
291
 *
292
 * PARAMETERS:  Filename            - AML input filename
293
 *              OutToFile           - TRUE if output should go to a file
294
 *              Prefix              - Path prefix for output
295
 *              OutFilename         - where the filename is returned
296
 *              GetAllTables        - TRUE if all tables are desired
297
 *
298
 * RETURN:      Status
299
 *
300
 * DESCRIPTION: Disassemble an entire ACPI table
301
 *
302
 *****************************************************************************/
303
 
304
ACPI_STATUS
305
AdAmlDisassemble (
306
    BOOLEAN                 OutToFile,
307
    char                    *Filename,
308
    char                    *Prefix,
309
    char                    **OutFilename,
310
    BOOLEAN                 GetAllTables)
311
{
312
    ACPI_STATUS             Status;
313
    char                    *DisasmFilename = NULL;
314
    char                    *ExternalFilename;
2216 Serge 315
    ACPI_EXTERNAL_FILE      *ExternalFileList = AcpiGbl_ExternalFileList;
1498 serge 316
    FILE                    *File = NULL;
317
    ACPI_TABLE_HEADER       *Table = NULL;
318
    ACPI_TABLE_HEADER       *ExternalTable;
319
    ACPI_OWNER_ID           OwnerId;
320
 
321
 
322
    /*
323
     * Input: AML code from either a file or via GetTables (memory or
324
     * registry)
325
     */
326
    if (Filename)
327
    {
328
        Status = AcpiDbGetTableFromFile (Filename, &Table);
329
        if (ACPI_FAILURE (Status))
330
        {
331
            return Status;
332
        }
333
 
334
        /*
335
         * External filenames separated by commas
336
         * Example: iasl -e file1,file2,file3 -d xxx.aml
337
         */
2216 Serge 338
        while (ExternalFileList)
1498 serge 339
        {
2216 Serge 340
            ExternalFilename = ExternalFileList->Path;
341
            if (!ACPI_STRCMP (ExternalFilename, Filename))
342
            {
343
                /* Next external file */
1498 serge 344
 
2216 Serge 345
                ExternalFileList = ExternalFileList->Next;
346
 
347
                continue;
348
            }
349
 
1498 serge 350
                Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable);
351
                if (ACPI_FAILURE (Status))
352
                {
353
                    return Status;
354
                }
355
 
356
                /* Load external table for symbol resolution */
357
 
358
                if (ExternalTable)
359
                {
360
                    Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
361
                    if (ACPI_FAILURE (Status))
362
                    {
363
                        AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
364
                            AcpiFormatException (Status));
365
                        return Status;
366
                    }
367
 
368
                    /*
369
                     * Load namespace from names created within control methods
370
                     * Set owner id of nodes in external table
371
                     */
372
                    AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
373
                        AcpiGbl_RootNode, OwnerId);
374
                    AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
375
                }
376
 
2216 Serge 377
            /* Next external file */
1498 serge 378
 
2216 Serge 379
            ExternalFileList = ExternalFileList->Next;
1498 serge 380
            }
381
 
382
            /* Clear external list generated by Scope in external tables */
383
 
2216 Serge 384
        if (AcpiGbl_ExternalFileList)
385
        {
1498 serge 386
            AcpiDmClearExternalList ();
387
        }
388
    }
389
    else
390
    {
391
        Status = AdGetLocalTables (Filename, GetAllTables);
392
        if (ACPI_FAILURE (Status))
393
        {
394
            AcpiOsPrintf ("Could not get ACPI tables, %s\n",
395
                AcpiFormatException (Status));
396
            return Status;
397
        }
398
 
399
        if (!AcpiGbl_DbOpt_disasm)
400
        {
401
            return AE_OK;
402
        }
403
 
404
        /* Obtained the local tables, just disassemble the DSDT */
405
 
406
        Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
407
        if (ACPI_FAILURE (Status))
408
        {
409
            AcpiOsPrintf ("Could not get DSDT, %s\n",
410
                AcpiFormatException (Status));
411
            return Status;
412
        }
413
 
414
        AcpiOsPrintf ("\nDisassembly of DSDT\n");
415
        Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
416
    }
417
 
418
    /*
419
     * Output:  ASL code. Redirect to a file if requested
420
     */
421
    if (OutToFile)
422
    {
423
        /* Create/Open a disassembly output file */
424
 
425
        DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
426
        if (!OutFilename)
427
        {
428
            fprintf (stderr, "Could not generate output filename\n");
429
            Status = AE_ERROR;
430
            goto Cleanup;
431
        }
432
 
433
        File = fopen (DisasmFilename, "w+");
434
        if (!File)
435
        {
436
            fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
437
            Status = AE_ERROR;
438
            goto Cleanup;
439
        }
440
 
441
        AcpiOsRedirectOutput (File);
442
    }
443
 
444
    *OutFilename = DisasmFilename;
445
 
446
    if (!AcpiUtIsAmlTable (Table))
447
    {
448
        AdDisassemblerHeader (Filename);
449
        AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
450
            Table->Signature);
451
        AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue\n */\n\n");
452
 
453
        AcpiDmDumpDataTable (Table);
454
        fprintf (stderr, "Acpi Data Table [%4.4s] decoded, written to \"%s\"\n",
455
            Table->Signature, DisasmFilename);
456
    }
457
    else
458
    {
459
        /* Always parse the tables, only option is what to display */
460
 
461
        Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
462
        if (ACPI_FAILURE (Status))
463
        {
464
            AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
465
                AcpiFormatException (Status));
466
            goto Cleanup;
467
        }
468
 
469
        if (AslCompilerdebug)
470
        {
471
            AcpiOsPrintf ("/**** Before second load\n");
472
 
473
            LsSetupNsList (File);
474
            LsDisplayNamespace ();
475
            AcpiOsPrintf ("*****/\n");
476
        }
477
 
478
        /*
479
         * Load namespace from names created within control methods
480
         */
481
        AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode, OwnerId);
482
 
483
        /*
484
         * Cross reference the namespace here, in order to generate External() statements
485
         */
486
        AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode, OwnerId);
487
 
488
        if (AslCompilerdebug)
489
        {
490
            AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
491
        }
492
 
493
        /* Find possible calls to external control methods */
494
 
495
        AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
496
 
497
        /* Convert fixed-offset references to resource descriptors to symbolic references */
498
 
499
        AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
500
 
501
        /*
502
         * If we found any external control methods, we must reparse the entire
503
         * tree with the new information (namely, the number of arguments per
504
         * method)
505
         */
506
        if (AcpiDmGetExternalMethodCount ())
507
        {
508
            fprintf (stderr,
509
                "\nFound %u external control methods, reparsing with new information\n",
510
                AcpiDmGetExternalMethodCount ());
511
 
512
            /*
513
             * Reparse, rebuild namespace. no need to xref namespace
514
             */
515
            AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
516
            AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
517
 
518
            AcpiGbl_RootNode                    = NULL;
519
            AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
520
            AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
521
            AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
522
            AcpiGbl_RootNodeStruct.Parent       = NULL;
523
            AcpiGbl_RootNodeStruct.Child        = NULL;
524
            AcpiGbl_RootNodeStruct.Peer         = NULL;
525
            AcpiGbl_RootNodeStruct.Object       = NULL;
526
            AcpiGbl_RootNodeStruct.Flags        = 0;
527
 
528
            Status = AcpiNsRootInitialize ();
529
            AcpiDmAddExternalsToNamespace ();
530
 
531
            /* Parse table. No need to reload it, however (FALSE) */
532
 
533
            Status = AdParseTable (Table, NULL, FALSE, FALSE);
534
            if (ACPI_FAILURE (Status))
535
            {
536
                AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
537
                    AcpiFormatException (Status));
538
                goto Cleanup;
539
            }
540
 
541
            if (AslCompilerdebug)
542
            {
543
                AcpiOsPrintf ("/**** After second load and resource conversion\n");
544
                LsSetupNsList (File);
545
                LsDisplayNamespace ();
546
                AcpiOsPrintf ("*****/\n");
547
 
548
                AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
549
            }
550
        }
551
 
552
        /* Optional displays */
553
 
554
        if (AcpiGbl_DbOpt_disasm)
555
        {
556
            AdDisplayTables (Filename, Table);
557
            fprintf (stderr,
558
                "Disassembly completed, written to \"%s\"\n",
559
                DisasmFilename);
560
        }
561
    }
562
 
563
Cleanup:
564
 
565
    if (Table && !AcpiUtIsAmlTable (Table))
566
    {
567
        ACPI_FREE (Table);
568
    }
569
 
570
    if (DisasmFilename)
571
    {
572
        ACPI_FREE (DisasmFilename);
573
    }
574
 
575
    if (OutToFile && File)
576
    {
577
 
578
#ifdef ASL_DISASM_DEBUG
579
        LsSetupNsList (File);
580
        LsDisplayNamespace ();
581
#endif
582
        fclose (File);
583
        AcpiOsRedirectOutput (stdout);
584
    }
585
 
586
    AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
587
    AcpiGbl_ParseOpRoot = NULL;
588
    return (Status);
589
}
590
 
591
 
592
/******************************************************************************
593
 *
594
 * FUNCTION:    AdDisassemblerHeader
595
 *
596
 * PARAMETERS:  Filename            - Input file for the table
597
 *
598
 * RETURN:      None
599
 *
600
 * DESCRIPTION: Create the disassembler header, including ACPI CA signon with
601
 *              current time and date.
602
 *
603
 *****************************************************************************/
604
 
605
void
606
AdDisassemblerHeader (
607
    char                    *Filename)
608
{
609
    time_t                  Timer;
610
 
611
    time (&Timer);
612
 
613
    /* Header and input table info */
614
 
2216 Serge 615
    AcpiOsPrintf ("/*\n");
616
    AcpiOsPrintf (ACPI_COMMON_HEADER ("AML Disassembler", " * "));
1498 serge 617
 
2216 Serge 618
    AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
1498 serge 619
    AcpiOsPrintf (" *\n");
620
}
621
 
622
 
623
/******************************************************************************
624
 *
625
 * FUNCTION:    AdCreateTableHeader
626
 *
627
 * PARAMETERS:  Filename            - Input file for the table
628
 *              Table               - Pointer to the raw table
629
 *
630
 * RETURN:      None
631
 *
632
 * DESCRIPTION: Create the ASL table header, including ACPI CA signon with
633
 *              current time and date.
634
 *
635
 *****************************************************************************/
636
 
2216 Serge 637
static void
1498 serge 638
AdCreateTableHeader (
639
    char                    *Filename,
640
    ACPI_TABLE_HEADER       *Table)
641
{
642
    char                    *NewFilename;
643
    UINT8                   Checksum;
644
 
645
 
646
    /*
647
     * Print file header and dump original table header
648
     */
649
    AdDisassemblerHeader (Filename);
650
 
2216 Serge 651
    AcpiOsPrintf (" * Original Table Header:\n");
1498 serge 652
    AcpiOsPrintf (" *     Signature        \"%4.4s\"\n",    Table->Signature);
653
    AcpiOsPrintf (" *     Length           0x%8.8X (%u)\n", Table->Length, Table->Length);
654
 
655
    /* Print and validate the revision */
656
 
657
    AcpiOsPrintf (" *     Revision         0x%2.2X",      Table->Revision);
658
 
659
    switch (Table->Revision)
660
    {
661
    case 0:
662
        AcpiOsPrintf (" **** Invalid Revision");
663
        break;
664
 
665
    case 1:
666
        /* Revision of DSDT controls the ACPI integer width */
667
 
668
        if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
669
        {
2216 Serge 670
            AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
1498 serge 671
        }
672
        break;
673
 
674
    default:
675
        break;
676
    }
677
    AcpiOsPrintf ("\n");
678
 
679
    /* Print and validate the table checksum */
680
 
681
    AcpiOsPrintf (" *     Checksum         0x%2.2X",        Table->Checksum);
682
 
683
    Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
684
    if (Checksum)
685
    {
686
        AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
687
            (UINT8) (Table->Checksum - Checksum));
688
    }
689
    AcpiOsPrintf ("\n");
690
 
691
    AcpiOsPrintf (" *     OEM ID           \"%.6s\"\n",     Table->OemId);
692
    AcpiOsPrintf (" *     OEM Table ID     \"%.8s\"\n",     Table->OemTableId);
693
    AcpiOsPrintf (" *     OEM Revision     0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
694
    AcpiOsPrintf (" *     Compiler ID      \"%.4s\"\n",     Table->AslCompilerId);
695
    AcpiOsPrintf (" *     Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
2216 Serge 696
    AcpiOsPrintf (" */\n\n");
1498 serge 697
 
698
    /* Create AML output filename based on input filename */
699
 
700
    if (Filename)
701
    {
702
        NewFilename = FlGenerateFilename (Filename, "aml");
703
    }
704
    else
705
    {
706
        NewFilename = ACPI_ALLOCATE_ZEROED (9);
707
        strncat (NewFilename, Table->Signature, 4);
708
        strcat (NewFilename, ".aml");
709
    }
710
 
711
    /* Open the ASL definition block */
712
 
713
    AcpiOsPrintf (
714
        "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
715
        NewFilename, Table->Signature, Table->Revision,
716
        Table->OemId, Table->OemTableId, Table->OemRevision);
717
 
718
    ACPI_FREE (NewFilename);
719
}
720
 
721
 
722
/******************************************************************************
723
 *
724
 * FUNCTION:    AdDisplayTables
725
 *
726
 * PARAMETERS:  Filename            - Input file for the table
727
 *              Table               - Pointer to the raw table
728
 *
729
 * RETURN:      Status
730
 *
731
 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
732
 *
733
 *****************************************************************************/
734
 
735
ACPI_STATUS
736
AdDisplayTables (
737
    char                    *Filename,
738
    ACPI_TABLE_HEADER       *Table)
739
{
740
 
741
 
742
    if (!AcpiGbl_ParseOpRoot)
743
    {
744
        return AE_NOT_EXIST;
745
    }
746
 
747
    if (!AcpiGbl_DbOpt_verbose)
748
    {
749
        AdCreateTableHeader (Filename, Table);
750
    }
751
 
752
    AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
753
 
754
    if (AcpiGbl_DbOpt_verbose)
755
    {
756
        AcpiOsPrintf ("\n\nTable Header:\n");
757
        AcpiUtDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
758
            DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
759
 
760
        AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
761
        AcpiUtDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), Table->Length,
762
            DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
763
    }
764
 
765
    return AE_OK;
766
}
767
 
768
 
769
/******************************************************************************
770
 *
771
 * FUNCTION:    AdDeferredParse
772
 *
773
 * PARAMETERS:  Op                  - Root Op of the deferred opcode
774
 *              Aml                 - Pointer to the raw AML
775
 *              AmlLength           - Length of the AML
776
 *
777
 * RETURN:      Status
778
 *
779
 * DESCRIPTION: Parse one deferred opcode
780
 *              (Methods, operation regions, etc.)
781
 *
782
 *****************************************************************************/
783
 
2216 Serge 784
static ACPI_STATUS
1498 serge 785
AdDeferredParse (
786
    ACPI_PARSE_OBJECT       *Op,
787
    UINT8                   *Aml,
788
    UINT32                  AmlLength)
789
{
790
    ACPI_WALK_STATE         *WalkState;
791
    ACPI_STATUS             Status;
792
    ACPI_PARSE_OBJECT       *SearchOp;
793
    ACPI_PARSE_OBJECT       *StartOp;
794
    UINT32                  BaseAmlOffset;
795
    ACPI_PARSE_OBJECT       *ExtraOp;
796
 
797
 
798
    ACPI_FUNCTION_TRACE (AdDeferredParse);
799
 
800
 
801
    fprintf (stderr, ".");
802
 
803
    if (!Aml || !AmlLength)
804
    {
805
        return_ACPI_STATUS (AE_OK);
806
    }
807
 
808
    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing %s [%4.4s]\n",
809
        Op->Common.AmlOpName, (char *) &Op->Named.Name));
810
 
811
    WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
812
    if (!WalkState)
813
    {
814
        return_ACPI_STATUS (AE_NO_MEMORY);
815
    }
816
 
817
    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml,
818
                    AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
819
    if (ACPI_FAILURE (Status))
820
    {
821
        return_ACPI_STATUS (Status);
822
    }
823
 
824
    /* Parse the method */
825
 
826
    WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
827
    WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
828
    Status = AcpiPsParseAml (WalkState);
829
 
830
    /*
831
     * We need to update all of the Aml offsets, since the parser thought
832
     * that the method began at offset zero.  In reality, it began somewhere
833
     * within the ACPI table, at the BaseAmlOffset.  Walk the entire tree that
834
     * was just created and update the AmlOffset in each Op
835
     */
836
    BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1;
837
    StartOp = (Op->Common.Value.Arg)->Common.Next;
838
    SearchOp = StartOp;
839
 
840
    /* Walk the parse tree */
841
 
842
    while (SearchOp)
843
    {
844
        SearchOp->Common.AmlOffset += BaseAmlOffset;
845
        SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
846
    }
847
 
848
    /*
849
     * Link the newly parsed subtree into the main parse tree
850
     */
851
    switch (Op->Common.AmlOpcode)
852
    {
853
    case AML_BUFFER_OP:
854
    case AML_PACKAGE_OP:
855
    case AML_VAR_PACKAGE_OP:
856
 
857
        switch (Op->Common.AmlOpcode)
858
        {
859
        case AML_PACKAGE_OP:
860
            ExtraOp = Op->Common.Value.Arg;
861
            ExtraOp = ExtraOp->Common.Next;
862
            Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
863
            break;
864
 
865
        case AML_VAR_PACKAGE_OP:
866
        case AML_BUFFER_OP:
867
        default:
868
            ExtraOp = Op->Common.Value.Arg;
869
            Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
870
            break;
871
        }
872
 
873
        /* Must point all parents to the main tree */
874
 
875
        StartOp = Op;
876
        SearchOp = StartOp;
877
        while (SearchOp)
878
        {
879
            if (SearchOp->Common.Parent == ExtraOp)
880
            {
881
                SearchOp->Common.Parent = Op;
882
            }
883
            SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
884
        }
885
        break;
886
 
887
    default:
888
        break;
889
    }
890
 
891
    return_ACPI_STATUS (AE_OK);
892
}
893
 
894
 
895
/******************************************************************************
896
 *
897
 * FUNCTION:    AdParseDeferredOps
898
 *
899
 * PARAMETERS:  Root                - Root of the parse tree
900
 *
901
 * RETURN:      Status
902
 *
903
 * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.)
904
 *
905
 *****************************************************************************/
906
 
2216 Serge 907
static ACPI_STATUS
1498 serge 908
AdParseDeferredOps (
909
    ACPI_PARSE_OBJECT       *Root)
910
{
911
    ACPI_PARSE_OBJECT       *Op = Root;
912
    ACPI_STATUS             Status = AE_OK;
913
    const ACPI_OPCODE_INFO  *OpInfo;
914
 
915
 
916
    ACPI_FUNCTION_NAME (AdParseDeferredOps);
917
    fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
918
 
919
    while (Op)
920
    {
921
        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
922
        if (!(OpInfo->Flags & AML_DEFER))
923
        {
924
            Op = AcpiPsGetDepthNext (Root, Op);
925
            continue;
926
        }
927
 
928
        switch (Op->Common.AmlOpcode)
929
        {
930
        case AML_METHOD_OP:
931
        case AML_BUFFER_OP:
932
        case AML_PACKAGE_OP:
933
        case AML_VAR_PACKAGE_OP:
934
 
935
            Status = AdDeferredParse (Op, Op->Named.Data, Op->Named.Length);
936
            if (ACPI_FAILURE (Status))
937
            {
938
                return_ACPI_STATUS (Status);
939
            }
940
            break;
941
 
942
        case AML_REGION_OP:
943
        case AML_CREATE_QWORD_FIELD_OP:
944
        case AML_CREATE_DWORD_FIELD_OP:
945
        case AML_CREATE_WORD_FIELD_OP:
946
        case AML_CREATE_BYTE_FIELD_OP:
947
        case AML_CREATE_BIT_FIELD_OP:
948
        case AML_CREATE_FIELD_OP:
949
        case AML_BANK_FIELD_OP:
950
 
951
            /* Nothing to do in these cases */
952
 
953
            break;
954
 
955
        default:
956
            ACPI_ERROR ((AE_INFO, "Unhandled deferred opcode [%s]",
957
                Op->Common.AmlOpName));
958
            break;
959
        }
960
 
961
        Op = AcpiPsGetDepthNext (Root, Op);
962
    }
963
 
964
    fprintf (stderr, "\n");
965
    return Status;
966
}
967
 
968
 
969
/******************************************************************************
970
 *
971
 * FUNCTION:    AdGetLocalTables
972
 *
973
 * PARAMETERS:  Filename            - Not used
974
 *              GetAllTables        - TRUE if all tables are desired
975
 *
976
 * RETURN:      Status
977
 *
978
 * DESCRIPTION: Get the ACPI tables from either memory or a file
979
 *
980
 *****************************************************************************/
981
 
982
ACPI_STATUS
983
AdGetLocalTables (
984
    char                    *Filename,
985
    BOOLEAN                 GetAllTables)
986
{
987
    ACPI_STATUS             Status;
988
    ACPI_TABLE_HEADER       TableHeader;
989
    ACPI_TABLE_HEADER       *NewTable;
990
    UINT32                  NumTables;
991
    UINT32                  PointerSize;
992
    UINT32                  TableIndex;
993
 
994
 
995
    if (GetAllTables)
996
    {
997
        ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT);
998
        AcpiOsTableOverride (&TableHeader, &NewTable);
999
        if (!NewTable)
1000
        {
1001
            fprintf (stderr, "Could not obtain RSDT\n");
1002
            return AE_NO_ACPI_TABLES;
1003
        }
1004
        else
1005
        {
1006
            AdWriteTable (NewTable, NewTable->Length,
1007
                ACPI_SIG_RSDT, NewTable->OemTableId);
1008
        }
1009
 
1010
        if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT))
1011
        {
1012
            PointerSize = sizeof (UINT32);
1013
        }
1014
        else
1015
        {
1016
            PointerSize = sizeof (UINT64);
1017
        }
1018
 
1019
        /*
1020
         * Determine the number of tables pointed to by the RSDT/XSDT.
1021
         * This is defined by the ACPI Specification to be the number of
1022
         * pointers contained within the RSDT/XSDT.  The size of the pointers
1023
         * is architecture-dependent.
1024
         */
1025
        NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize;
1026
        AcpiOsPrintf ("There are %u tables defined in the %4.4s\n\n",
1027
            NumTables, NewTable->Signature);
1028
 
1029
        /* Get the FADT */
1030
 
1031
        ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT);
1032
        AcpiOsTableOverride (&TableHeader, &NewTable);
1033
        if (NewTable)
1034
        {
1035
            AdWriteTable (NewTable, NewTable->Length,
1036
                ACPI_SIG_FADT, NewTable->OemTableId);
1037
        }
1038
        AcpiOsPrintf ("\n");
1039
 
1040
        /* Don't bother with FACS, it is usually all zeros */
1041
    }
1042
 
1043
    /* Always get the DSDT */
1044
 
1045
    ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
1046
    AcpiOsTableOverride (&TableHeader, &NewTable);
1047
    if (NewTable)
1048
    {
1049
        AdWriteTable (NewTable, NewTable->Length,
1050
            ACPI_SIG_DSDT, NewTable->OemTableId);
1051
 
1052
        /* Store DSDT in the Table Manager */
1053
 
1054
        Status = AcpiTbStoreTable (0, NewTable, NewTable->Length,
1055
                    0, &TableIndex);
1056
        if (ACPI_FAILURE (Status))
1057
        {
1058
            fprintf (stderr, "Could not store DSDT\n");
1059
            return AE_NO_ACPI_TABLES;
1060
        }
1061
    }
1062
    else
1063
    {
1064
        fprintf (stderr, "Could not obtain DSDT\n");
1065
        return AE_NO_ACPI_TABLES;
1066
    }
1067
 
1068
#if 0
1069
    /* TBD: Future implementation */
1070
 
1071
    AcpiOsPrintf ("\n");
1072
 
1073
    /* Get all SSDTs */
1074
 
1075
    ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT);
1076
    do
1077
    {
1078
        NewTable = NULL;
1079
        Status = AcpiOsTableOverride (&TableHeader, &NewTable);
1080
 
1081
    } while (NewTable);
1082
#endif
1083
 
1084
    return AE_OK;
1085
}
1086
 
1087
 
1088
/******************************************************************************
1089
 *
1090
 * FUNCTION:    AdParseTable
1091
 *
1092
 * PARAMETERS:  Table               - Pointer to the raw table
1093
 *              OwnerId             - Returned OwnerId of the table
1094
 *              LoadTable           - If add table to the global table list
1095
 *              External            - If this is an external table
1096
 *
1097
 * RETURN:      Status
1098
 *
1099
 * DESCRIPTION: Parse the DSDT.
1100
 *
1101
 *****************************************************************************/
1102
 
1103
ACPI_STATUS
1104
AdParseTable (
1105
    ACPI_TABLE_HEADER       *Table,
1106
    ACPI_OWNER_ID           *OwnerId,
1107
    BOOLEAN                 LoadTable,
1108
    BOOLEAN                 External)
1109
{
1110
    ACPI_STATUS             Status = AE_OK;
1111
    ACPI_WALK_STATE         *WalkState;
1112
    UINT8                   *AmlStart;
1113
    UINT32                  AmlLength;
1114
    UINT32                  TableIndex;
1115
 
1116
 
1117
    if (!Table)
1118
    {
1119
        return AE_NOT_EXIST;
1120
    }
1121
 
1122
    /* Pass 1:  Parse everything except control method bodies */
1123
 
1124
    fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
1125
 
1126
    AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
1127
    AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
1128
 
1129
    /* Create the root object */
1130
 
1131
    AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp ();
1132
    if (!AcpiGbl_ParseOpRoot)
1133
    {
1134
        return AE_NO_MEMORY;
1135
    }
1136
 
1137
    /* Create and initialize a new walk state */
1138
 
1139
    WalkState = AcpiDsCreateWalkState (0,
1140
                        AcpiGbl_ParseOpRoot, NULL, NULL);
1141
    if (!WalkState)
1142
    {
1143
        return (AE_NO_MEMORY);
1144
    }
1145
 
1146
    Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
1147
                NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
1148
    if (ACPI_FAILURE (Status))
1149
    {
1150
        return (Status);
1151
    }
1152
 
1153
    WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
1154
    WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
1155
 
1156
    Status = AcpiPsParseAml (WalkState);
1157
    if (ACPI_FAILURE (Status))
1158
    {
1159
        return Status;
1160
    }
1161
 
1162
    /* If LoadTable is FALSE, we are parsing the last loaded table */
1163
 
1164
    TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
1165
 
1166
    /* Pass 2 */
1167
 
1168
    if (LoadTable)
1169
    {
1170
        Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table,
1171
                    Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex);
1172
        if (ACPI_FAILURE (Status))
1173
        {
1174
            return Status;
1175
        }
1176
        Status = AcpiTbAllocateOwnerId (TableIndex);
1177
        if (ACPI_FAILURE (Status))
1178
        {
1179
            return Status;
1180
        }
1181
        if (OwnerId)
1182
        {
1183
            Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
1184
            if (ACPI_FAILURE (Status))
1185
            {
1186
                return Status;
1187
            }
1188
        }
1189
    }
1190
 
1191
    fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
1192
 
1193
    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
1194
    if (ACPI_FAILURE (Status))
1195
    {
1196
        return (Status);
1197
    }
1198
 
1199
    /* No need to parse control methods of external table */
1200
 
1201
    if (External)
1202
    {
1203
        return AE_OK;
1204
    }
1205
 
1206
    /* Pass 3: Parse control methods and link their parse trees into the main parse tree */
1207
 
1208
    Status = AdParseDeferredOps (AcpiGbl_ParseOpRoot);
1209
 
1210
    /* Process Resource Templates */
1211
 
1212
    AcpiDmFindResources (AcpiGbl_ParseOpRoot);
1213
 
1214
    fprintf (stderr, "Parsing completed\n");
1215
    return AE_OK;
1216
}
1217