adisasm.c revision 284460
1/******************************************************************************
2 *
3 * Module Name: adisasm - Application-level disassembler routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/compiler/aslcompiler.h>
45#include <contrib/dev/acpica/include/acparser.h>
46#include <contrib/dev/acpica/include/amlcode.h>
47#include <contrib/dev/acpica/include/acdisasm.h>
48#include <contrib/dev/acpica/include/acdispat.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50#include <contrib/dev/acpica/include/actables.h>
51#include <contrib/dev/acpica/include/acapps.h>
52
53#include <stdio.h>
54#include <time.h>
55
56
57#define _COMPONENT          ACPI_TOOLS
58        ACPI_MODULE_NAME    ("adisasm")
59
60/* Local prototypes */
61
62static void
63AdCreateTableHeader (
64    char                    *Filename,
65    ACPI_TABLE_HEADER       *Table);
66
67static ACPI_STATUS
68AdStoreTable (
69    ACPI_TABLE_HEADER       *Table,
70    UINT32                  *TableIndex);
71
72/* Stubs for ASL compiler */
73
74#ifndef ACPI_ASL_COMPILER
75BOOLEAN
76AcpiDsIsResultUsed (
77    ACPI_PARSE_OBJECT       *Op,
78    ACPI_WALK_STATE         *WalkState)
79{
80    return TRUE;
81}
82
83ACPI_STATUS
84AcpiDsMethodError (
85    ACPI_STATUS             Status,
86    ACPI_WALK_STATE         *WalkState)
87{
88    return (Status);
89}
90#endif
91
92ACPI_STATUS
93AcpiNsLoadTable (
94    UINT32                  TableIndex,
95    ACPI_NAMESPACE_NODE     *Node)
96{
97    return (AE_NOT_IMPLEMENTED);
98}
99
100ACPI_STATUS
101AcpiDsRestartControlMethod (
102    ACPI_WALK_STATE         *WalkState,
103    ACPI_OPERAND_OBJECT     *ReturnDesc)
104{
105    return (AE_OK);
106}
107
108void
109AcpiDsTerminateControlMethod (
110    ACPI_OPERAND_OBJECT     *MethodDesc,
111    ACPI_WALK_STATE         *WalkState)
112{
113    return;
114}
115
116ACPI_STATUS
117AcpiDsCallControlMethod (
118    ACPI_THREAD_STATE       *Thread,
119    ACPI_WALK_STATE         *WalkState,
120    ACPI_PARSE_OBJECT       *Op)
121{
122    return (AE_OK);
123}
124
125ACPI_STATUS
126AcpiDsMethodDataInitArgs (
127    ACPI_OPERAND_OBJECT     **Params,
128    UINT32                  MaxParamCount,
129    ACPI_WALK_STATE         *WalkState)
130{
131    return (AE_OK);
132}
133
134
135static ACPI_TABLE_DESC      LocalTables[1];
136ACPI_PARSE_OBJECT    *AcpiGbl_ParseOpRoot;
137
138
139/*******************************************************************************
140 *
141 * FUNCTION:    AdInitialize
142 *
143 * PARAMETERS:  None
144 *
145 * RETURN:      Status
146 *
147 * DESCRIPTION: ACPICA and local initialization
148 *
149 ******************************************************************************/
150
151ACPI_STATUS
152AdInitialize (
153    void)
154{
155    ACPI_STATUS             Status;
156
157
158    /* ACPICA subsystem initialization */
159
160    Status = AcpiOsInitialize ();
161    if (ACPI_FAILURE (Status))
162    {
163        return (Status);
164    }
165
166    Status = AcpiUtInitGlobals ();
167    if (ACPI_FAILURE (Status))
168    {
169        return (Status);
170    }
171
172    Status = AcpiUtMutexInitialize ();
173    if (ACPI_FAILURE (Status))
174    {
175        return (Status);
176    }
177
178    Status = AcpiNsRootInitialize ();
179    if (ACPI_FAILURE (Status))
180    {
181        return (Status);
182    }
183
184    /* Setup the Table Manager (cheat - there is no RSDT) */
185
186    AcpiGbl_RootTableList.MaxTableCount = 1;
187    AcpiGbl_RootTableList.CurrentTableCount = 0;
188    AcpiGbl_RootTableList.Tables = LocalTables;
189
190    return (Status);
191}
192
193
194/******************************************************************************
195 *
196 * FUNCTION:    AdAmlDisassemble
197 *
198 * PARAMETERS:  Filename            - AML input filename
199 *              OutToFile           - TRUE if output should go to a file
200 *              Prefix              - Path prefix for output
201 *              OutFilename         - where the filename is returned
202 *
203 * RETURN:      Status
204 *
205 * DESCRIPTION: Disassemble an entire ACPI table
206 *
207 *****************************************************************************/
208
209ACPI_STATUS
210AdAmlDisassemble (
211    BOOLEAN                 OutToFile,
212    char                    *Filename,
213    char                    *Prefix,
214    char                    **OutFilename)
215{
216    ACPI_STATUS             Status;
217    ACPI_STATUS             GlobalStatus = AE_OK;
218    char                    *DisasmFilename = NULL;
219    char                    *ExternalFilename;
220    ACPI_EXTERNAL_FILE      *ExternalFileList = AcpiGbl_ExternalFileList;
221    FILE                    *File = NULL;
222    ACPI_TABLE_HEADER       *Table = NULL;
223    ACPI_TABLE_HEADER       *ExternalTable;
224    ACPI_OWNER_ID           OwnerId;
225
226
227    /*
228     * Input: AML code from either a file or via GetTables (memory or
229     * registry)
230     */
231    if (Filename)
232    {
233        Status = AcpiDbGetTableFromFile (Filename, &Table, FALSE);
234        if (ACPI_FAILURE (Status))
235        {
236            return (Status);
237        }
238
239        /*
240         * External filenames separated by commas
241         * Example: iasl -e file1,file2,file3 -d xxx.aml
242         */
243        while (ExternalFileList)
244        {
245            ExternalFilename = ExternalFileList->Path;
246            if (!ACPI_STRCMP (ExternalFilename, Filename))
247            {
248                /* Next external file */
249
250                ExternalFileList = ExternalFileList->Next;
251                continue;
252            }
253
254            Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable, TRUE);
255            if (ACPI_FAILURE (Status))
256            {
257                if (Status == AE_TYPE)
258                {
259                    ExternalFileList = ExternalFileList->Next;
260                    GlobalStatus = AE_TYPE;
261                    Status = AE_OK;
262                    continue;
263                }
264                return (Status);
265            }
266
267            /* Load external table for symbol resolution */
268
269            if (ExternalTable)
270            {
271                Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
272                if (ACPI_FAILURE (Status))
273                {
274                    AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
275                        AcpiFormatException (Status));
276                    return (Status);
277                }
278
279                /*
280                 * Load namespace from names created within control methods
281                 * Set owner id of nodes in external table
282                 */
283                AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
284                    AcpiGbl_RootNode, OwnerId);
285                AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
286            }
287
288            /* Next external file */
289
290            ExternalFileList = ExternalFileList->Next;
291        }
292
293        if (ACPI_FAILURE (GlobalStatus))
294        {
295            return (GlobalStatus);
296        }
297
298        /* Clear external list generated by Scope in external tables */
299
300        if (AcpiGbl_ExternalFileList)
301        {
302            AcpiDmClearExternalList ();
303        }
304
305        /* Load any externals defined in the optional external ref file */
306
307        AcpiDmGetExternalsFromFile ();
308    }
309    else
310    {
311        Status = AdGetLocalTables ();
312        if (ACPI_FAILURE (Status))
313        {
314            AcpiOsPrintf ("Could not get ACPI tables, %s\n",
315                AcpiFormatException (Status));
316            return (Status);
317        }
318
319        if (!AcpiGbl_DbOpt_Disasm)
320        {
321            return (AE_OK);
322        }
323
324        /* Obtained the local tables, just disassemble the DSDT */
325
326        Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
327        if (ACPI_FAILURE (Status))
328        {
329            AcpiOsPrintf ("Could not get DSDT, %s\n",
330                AcpiFormatException (Status));
331            return (Status);
332        }
333
334        AcpiOsPrintf ("\nDisassembly of DSDT\n");
335        Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
336    }
337
338    /*
339     * Output: ASL code. Redirect to a file if requested
340     */
341    if (OutToFile)
342    {
343        /* Create/Open a disassembly output file */
344
345        DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
346        if (!DisasmFilename)
347        {
348            fprintf (stderr, "Could not generate output filename\n");
349            Status = AE_ERROR;
350            goto Cleanup;
351        }
352
353        File = fopen (DisasmFilename, "w+");
354        if (!File)
355        {
356            fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
357            Status = AE_ERROR;
358            goto Cleanup;
359        }
360
361        AcpiOsRedirectOutput (File);
362    }
363
364    *OutFilename = DisasmFilename;
365
366    /* ForceAmlDisassembly means to assume the table contains valid AML */
367
368    if (!AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table))
369    {
370        AdDisassemblerHeader (Filename, ACPI_IS_DATA_TABLE);
371        AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
372            Table->Signature);
373        AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]  "
374            "FieldName : FieldValue\n */\n\n");
375
376        AcpiDmDumpDataTable (Table);
377        fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n",
378            Table->Signature);
379
380        if (File)
381        {
382            fprintf (stderr, "Formatted output:  %s - %u bytes\n",
383                DisasmFilename, CmGetFileSize (File));
384        }
385    }
386    else
387    {
388        /* Always parse the tables, only option is what to display */
389
390        Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
391        if (ACPI_FAILURE (Status))
392        {
393            AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
394                AcpiFormatException (Status));
395            goto Cleanup;
396        }
397
398        if (AslCompilerdebug)
399        {
400            AcpiOsPrintf ("/**** Before second load\n");
401
402            if (File)
403            {
404                NsSetupNamespaceListing (File);
405                NsDisplayNamespace ();
406            }
407            AcpiOsPrintf ("*****/\n");
408        }
409
410        /* Load namespace from names created within control methods */
411
412        AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
413            AcpiGbl_RootNode, OwnerId);
414
415        /*
416         * Cross reference the namespace here, in order to
417         * generate External() statements
418         */
419        AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
420            AcpiGbl_RootNode, OwnerId);
421
422        if (AslCompilerdebug)
423        {
424            AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
425        }
426
427        /* Find possible calls to external control methods */
428
429        AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
430
431        /*
432         * If we found any external control methods, we must reparse
433         * the entire tree with the new information (namely, the
434         * number of arguments per method)
435         */
436        if (AcpiDmGetExternalMethodCount ())
437        {
438            fprintf (stderr,
439                "\nFound %u external control methods, "
440                "reparsing with new information\n",
441                AcpiDmGetExternalMethodCount ());
442
443            /* Reparse, rebuild namespace */
444
445            AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
446            AcpiGbl_ParseOpRoot = NULL;
447            AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
448
449            AcpiGbl_RootNode                    = NULL;
450            AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
451            AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
452            AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
453            AcpiGbl_RootNodeStruct.Parent       = NULL;
454            AcpiGbl_RootNodeStruct.Child        = NULL;
455            AcpiGbl_RootNodeStruct.Peer         = NULL;
456            AcpiGbl_RootNodeStruct.Object       = NULL;
457            AcpiGbl_RootNodeStruct.Flags        = 0;
458
459            Status = AcpiNsRootInitialize ();
460
461            /* New namespace, add the external definitions first */
462
463            AcpiDmAddExternalsToNamespace ();
464
465            /* Parse the table again. No need to reload it, however */
466
467            Status = AdParseTable (Table, NULL, FALSE, FALSE);
468            if (ACPI_FAILURE (Status))
469            {
470                AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
471                    AcpiFormatException (Status));
472                goto Cleanup;
473            }
474
475            /* Cross reference the namespace again */
476
477            AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
478                AcpiGbl_RootNode, OwnerId);
479
480            AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
481                AcpiGbl_RootNode, OwnerId);
482
483            if (AslCompilerdebug)
484            {
485                AcpiOsPrintf ("/**** After second load and resource conversion\n");
486                if (File)
487                {
488                    NsSetupNamespaceListing (File);
489                    NsDisplayNamespace ();
490                }
491                AcpiOsPrintf ("*****/\n");
492
493                AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
494            }
495        }
496
497        /*
498         * Now that the namespace is finalized, we can perform namespace
499         * transforms.
500         *
501         * 1) Convert fixed-offset references to resource descriptors
502         *    to symbolic references (Note: modifies namespace)
503         */
504        AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
505
506        /* Optional displays */
507
508        if (AcpiGbl_DbOpt_Disasm)
509        {
510            /* This is the real disassembly */
511
512            AdDisplayTables (Filename, Table);
513
514            /* Dump hex table if requested (-vt) */
515
516            AcpiDmDumpDataTable (Table);
517
518            fprintf (stderr, "Disassembly completed\n");
519            if (File)
520            {
521                fprintf (stderr, "ASL Output:    %s - %u bytes\n",
522                    DisasmFilename, CmGetFileSize (File));
523            }
524
525            if (Gbl_MapfileFlag)
526            {
527                fprintf (stderr, "%14s %s - %u bytes\n",
528                    Gbl_Files[ASL_FILE_MAP_OUTPUT].ShortDescription,
529                    Gbl_Files[ASL_FILE_MAP_OUTPUT].Filename,
530                    FlGetFileSize (ASL_FILE_MAP_OUTPUT));
531            }
532        }
533    }
534
535Cleanup:
536
537    if (Table && !AcpiGbl_ForceAmlDisassembly &&!AcpiUtIsAmlTable (Table))
538    {
539        ACPI_FREE (Table);
540    }
541
542    if (File)
543    {
544        if (AslCompilerdebug) /* Display final namespace, with transforms */
545        {
546            NsSetupNamespaceListing (File);
547            NsDisplayNamespace ();
548        }
549
550        fclose (File);
551        AcpiOsRedirectOutput (stdout);
552    }
553
554    AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
555    AcpiGbl_ParseOpRoot = NULL;
556    return (Status);
557}
558
559
560/******************************************************************************
561 *
562 * FUNCTION:    AdDisassemblerHeader
563 *
564 * PARAMETERS:  Filename            - Input file for the table
565 *              TableType           - Either AML or DataTable
566 *
567 * RETURN:      None
568 *
569 * DESCRIPTION: Create the disassembler header, including ACPICA signon with
570 *              current time and date.
571 *
572 *****************************************************************************/
573
574void
575AdDisassemblerHeader (
576    char                    *Filename,
577    UINT8                   TableType)
578{
579    time_t                  Timer;
580
581
582    time (&Timer);
583
584    /* Header and input table info */
585
586    AcpiOsPrintf ("/*\n");
587    AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * "));
588
589    if (TableType == ACPI_IS_AML_TABLE)
590    {
591        if (AcpiGbl_CstyleDisassembly)
592        {
593            AcpiOsPrintf (
594                " * Disassembling to symbolic ASL+ operators\n"
595                " *\n");
596        }
597        else
598        {
599            AcpiOsPrintf (
600                " * Disassembling to non-symbolic legacy ASL operators\n"
601                " *\n");
602        }
603    }
604
605    AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
606    AcpiOsPrintf (" *\n");
607}
608
609
610/******************************************************************************
611 *
612 * FUNCTION:    AdCreateTableHeader
613 *
614 * PARAMETERS:  Filename            - Input file for the table
615 *              Table               - Pointer to the raw table
616 *
617 * RETURN:      None
618 *
619 * DESCRIPTION: Create the ASL table header, including ACPICA signon with
620 *              current time and date.
621 *
622 *****************************************************************************/
623
624static void
625AdCreateTableHeader (
626    char                    *Filename,
627    ACPI_TABLE_HEADER       *Table)
628{
629    char                    *NewFilename;
630    UINT8                   Checksum;
631
632
633    /*
634     * Print file header and dump original table header
635     */
636    AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE);
637
638    AcpiOsPrintf (" * Original Table Header:\n");
639    AcpiOsPrintf (" *     Signature        \"%4.4s\"\n",    Table->Signature);
640    AcpiOsPrintf (" *     Length           0x%8.8X (%u)\n", Table->Length, Table->Length);
641
642    /* Print and validate the revision */
643
644    AcpiOsPrintf (" *     Revision         0x%2.2X",      Table->Revision);
645
646    switch (Table->Revision)
647    {
648    case 0:
649
650        AcpiOsPrintf (" **** Invalid Revision");
651        break;
652
653    case 1:
654
655        /* Revision of DSDT controls the ACPI integer width */
656
657        if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
658        {
659            AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
660        }
661        break;
662
663    default:
664
665        break;
666    }
667    AcpiOsPrintf ("\n");
668
669    /* Print and validate the table checksum */
670
671    AcpiOsPrintf (" *     Checksum         0x%2.2X",        Table->Checksum);
672
673    Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
674    if (Checksum)
675    {
676        AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
677            (UINT8) (Table->Checksum - Checksum));
678    }
679    AcpiOsPrintf ("\n");
680
681    AcpiOsPrintf (" *     OEM ID           \"%.6s\"\n",     Table->OemId);
682    AcpiOsPrintf (" *     OEM Table ID     \"%.8s\"\n",     Table->OemTableId);
683    AcpiOsPrintf (" *     OEM Revision     0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
684    AcpiOsPrintf (" *     Compiler ID      \"%.4s\"\n",     Table->AslCompilerId);
685    AcpiOsPrintf (" *     Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
686    AcpiOsPrintf (" */\n");
687
688    /* Create AML output filename based on input filename */
689
690    if (Filename)
691    {
692        NewFilename = FlGenerateFilename (Filename, "aml");
693    }
694    else
695    {
696        NewFilename = UtStringCacheCalloc (9);
697        if (NewFilename)
698        {
699            strncat (NewFilename, Table->Signature, 4);
700            strcat (NewFilename, ".aml");
701        }
702    }
703
704    if (!NewFilename)
705    {
706        AcpiOsPrintf (" **** Could not generate AML output filename\n");
707        return;
708    }
709
710    /* Open the ASL definition block */
711
712    AcpiOsPrintf (
713        "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
714        NewFilename, Table->Signature, Table->Revision,
715        Table->OemId, Table->OemTableId, Table->OemRevision);
716}
717
718
719/******************************************************************************
720 *
721 * FUNCTION:    AdDisplayTables
722 *
723 * PARAMETERS:  Filename            - Input file for the table
724 *              Table               - Pointer to the raw table
725 *
726 * RETURN:      Status
727 *
728 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
729 *
730 *****************************************************************************/
731
732ACPI_STATUS
733AdDisplayTables (
734    char                    *Filename,
735    ACPI_TABLE_HEADER       *Table)
736{
737
738
739    if (!AcpiGbl_ParseOpRoot)
740    {
741        return (AE_NOT_EXIST);
742    }
743
744    if (!AcpiGbl_DbOpt_Verbose)
745    {
746        AdCreateTableHeader (Filename, Table);
747    }
748
749    AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
750    MpEmitMappingInfo ();
751
752    if (AcpiGbl_DbOpt_Verbose)
753    {
754        AcpiOsPrintf ("\n\nTable Header:\n");
755        AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
756            DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
757
758        AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
759        AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)),
760            Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
761    }
762
763    return (AE_OK);
764}
765
766
767/*******************************************************************************
768 *
769 * FUNCTION:    AdStoreTable
770 *
771 * PARAMETERS:  Table               - Table header
772 *              TableIndex          - Where the table index is returned
773 *
774 * RETURN:      Status and table index.
775 *
776 * DESCRIPTION: Add an ACPI table to the global table list
777 *
778 ******************************************************************************/
779
780static ACPI_STATUS
781AdStoreTable (
782    ACPI_TABLE_HEADER       *Table,
783    UINT32                  *TableIndex)
784{
785    ACPI_STATUS             Status;
786    ACPI_TABLE_DESC         *TableDesc;
787
788
789    Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc);
790    if (ACPI_FAILURE (Status))
791    {
792        return (Status);
793    }
794
795    /* Initialize added table */
796
797    AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table),
798        ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table);
799    AcpiTbValidateTable (TableDesc);
800    return (AE_OK);
801}
802
803
804/******************************************************************************
805 *
806 * FUNCTION:    AdGetLocalTables
807 *
808 * PARAMETERS:  None
809 *
810 * RETURN:      Status
811 *
812 * DESCRIPTION: Get the ACPI tables from either memory or a file
813 *
814 *****************************************************************************/
815
816ACPI_STATUS
817AdGetLocalTables (
818    void)
819{
820    ACPI_STATUS             Status;
821    ACPI_TABLE_HEADER       TableHeader;
822    ACPI_TABLE_HEADER       *NewTable;
823    UINT32                  TableIndex;
824
825
826    /* Get the DSDT via table override */
827
828    ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
829    AcpiOsTableOverride (&TableHeader, &NewTable);
830    if (!NewTable)
831    {
832        fprintf (stderr, "Could not obtain DSDT\n");
833        return (AE_NO_ACPI_TABLES);
834    }
835
836    AdWriteTable (NewTable, NewTable->Length,
837        ACPI_SIG_DSDT, NewTable->OemTableId);
838
839    /* Store DSDT in the Table Manager */
840
841    Status = AdStoreTable (NewTable, &TableIndex);
842    if (ACPI_FAILURE (Status))
843    {
844        fprintf (stderr, "Could not store DSDT\n");
845        return (AE_NO_ACPI_TABLES);
846    }
847
848    return (AE_OK);
849}
850
851
852/******************************************************************************
853 *
854 * FUNCTION:    AdParseTable
855 *
856 * PARAMETERS:  Table               - Pointer to the raw table
857 *              OwnerId             - Returned OwnerId of the table
858 *              LoadTable           - If add table to the global table list
859 *              External            - If this is an external table
860 *
861 * RETURN:      Status
862 *
863 * DESCRIPTION: Parse the DSDT.
864 *
865 *****************************************************************************/
866
867ACPI_STATUS
868AdParseTable (
869    ACPI_TABLE_HEADER       *Table,
870    ACPI_OWNER_ID           *OwnerId,
871    BOOLEAN                 LoadTable,
872    BOOLEAN                 External)
873{
874    ACPI_STATUS             Status = AE_OK;
875    ACPI_WALK_STATE         *WalkState;
876    UINT8                   *AmlStart;
877    UINT32                  AmlLength;
878    UINT32                  TableIndex;
879
880
881    if (!Table)
882    {
883        return (AE_NOT_EXIST);
884    }
885
886    /* Pass 1:  Parse everything except control method bodies */
887
888    fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
889
890    AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
891    AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
892
893    /* Create the root object */
894
895    AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp ();
896    if (!AcpiGbl_ParseOpRoot)
897    {
898        return (AE_NO_MEMORY);
899    }
900
901    /* Create and initialize a new walk state */
902
903    WalkState = AcpiDsCreateWalkState (0,
904                        AcpiGbl_ParseOpRoot, NULL, NULL);
905    if (!WalkState)
906    {
907        return (AE_NO_MEMORY);
908    }
909
910    Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
911                NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
912    if (ACPI_FAILURE (Status))
913    {
914        return (Status);
915    }
916
917    WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
918    WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
919
920    Status = AcpiPsParseAml (WalkState);
921    if (ACPI_FAILURE (Status))
922    {
923        return (Status);
924    }
925
926    /* If LoadTable is FALSE, we are parsing the last loaded table */
927
928    TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
929
930    /* Pass 2 */
931
932    if (LoadTable)
933    {
934        Status = AdStoreTable (Table, &TableIndex);
935        if (ACPI_FAILURE (Status))
936        {
937            return (Status);
938        }
939        Status = AcpiTbAllocateOwnerId (TableIndex);
940        if (ACPI_FAILURE (Status))
941        {
942            return (Status);
943        }
944        if (OwnerId)
945        {
946            Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
947            if (ACPI_FAILURE (Status))
948            {
949                return (Status);
950            }
951        }
952    }
953
954    fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
955
956    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
957    if (ACPI_FAILURE (Status))
958    {
959        return (Status);
960    }
961
962    /* No need to parse control methods of external table */
963
964    if (External)
965    {
966        return (AE_OK);
967    }
968
969    /*
970     * Pass 3: Parse control methods and link their parse trees
971     * into the main parse tree
972     */
973    fprintf (stderr,
974        "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
975    Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot);
976    fprintf (stderr, "\n");
977
978    /* Process Resource Templates */
979
980    AcpiDmFindResources (AcpiGbl_ParseOpRoot);
981
982    fprintf (stderr, "Parsing completed\n");
983    return (AE_OK);
984}
985