adisasm.c revision 281687
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    char                    *DisasmFilename = NULL;
218    char                    *ExternalFilename;
219    ACPI_EXTERNAL_FILE      *ExternalFileList = AcpiGbl_ExternalFileList;
220    FILE                    *File = NULL;
221    ACPI_TABLE_HEADER       *Table = NULL;
222    ACPI_TABLE_HEADER       *ExternalTable;
223    ACPI_OWNER_ID           OwnerId;
224
225
226    /*
227     * Input: AML code from either a file or via GetTables (memory or
228     * registry)
229     */
230    if (Filename)
231    {
232        Status = AcpiDbGetTableFromFile (Filename, &Table);
233        if (ACPI_FAILURE (Status))
234        {
235            return (Status);
236        }
237
238        /*
239         * External filenames separated by commas
240         * Example: iasl -e file1,file2,file3 -d xxx.aml
241         */
242        while (ExternalFileList)
243        {
244            ExternalFilename = ExternalFileList->Path;
245            if (!ACPI_STRCMP (ExternalFilename, Filename))
246            {
247                /* Next external file */
248
249                ExternalFileList = ExternalFileList->Next;
250                continue;
251            }
252
253            Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable);
254            if (ACPI_FAILURE (Status))
255            {
256                return (Status);
257            }
258
259            /* Load external table for symbol resolution */
260
261            if (ExternalTable)
262            {
263                Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
264                if (ACPI_FAILURE (Status))
265                {
266                    AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
267                        AcpiFormatException (Status));
268                    return (Status);
269                }
270
271                /*
272                 * Load namespace from names created within control methods
273                 * Set owner id of nodes in external table
274                 */
275                AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
276                    AcpiGbl_RootNode, OwnerId);
277                AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
278            }
279
280            /* Next external file */
281
282            ExternalFileList = ExternalFileList->Next;
283        }
284
285        /* Clear external list generated by Scope in external tables */
286
287        if (AcpiGbl_ExternalFileList)
288        {
289            AcpiDmClearExternalList ();
290        }
291
292        /* Load any externals defined in the optional external ref file */
293
294        AcpiDmGetExternalsFromFile ();
295    }
296    else
297    {
298        Status = AdGetLocalTables ();
299        if (ACPI_FAILURE (Status))
300        {
301            AcpiOsPrintf ("Could not get ACPI tables, %s\n",
302                AcpiFormatException (Status));
303            return (Status);
304        }
305
306        if (!AcpiGbl_DbOpt_Disasm)
307        {
308            return (AE_OK);
309        }
310
311        /* Obtained the local tables, just disassemble the DSDT */
312
313        Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
314        if (ACPI_FAILURE (Status))
315        {
316            AcpiOsPrintf ("Could not get DSDT, %s\n",
317                AcpiFormatException (Status));
318            return (Status);
319        }
320
321        AcpiOsPrintf ("\nDisassembly of DSDT\n");
322        Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
323    }
324
325    /*
326     * Output: ASL code. Redirect to a file if requested
327     */
328    if (OutToFile)
329    {
330        /* Create/Open a disassembly output file */
331
332        DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
333        if (!DisasmFilename)
334        {
335            fprintf (stderr, "Could not generate output filename\n");
336            Status = AE_ERROR;
337            goto Cleanup;
338        }
339
340        File = fopen (DisasmFilename, "w+");
341        if (!File)
342        {
343            fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
344            Status = AE_ERROR;
345            goto Cleanup;
346        }
347
348        AcpiOsRedirectOutput (File);
349    }
350
351    *OutFilename = DisasmFilename;
352
353    /* ForceAmlDisassembly means to assume the table contains valid AML */
354
355    if (!AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table))
356    {
357        AdDisassemblerHeader (Filename, ACPI_IS_DATA_TABLE);
358        AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
359            Table->Signature);
360        AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]  "
361            "FieldName : FieldValue\n */\n\n");
362
363        AcpiDmDumpDataTable (Table);
364        fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n",
365            Table->Signature);
366
367        if (File)
368        {
369            fprintf (stderr, "Formatted output:  %s - %u bytes\n",
370                DisasmFilename, CmGetFileSize (File));
371        }
372    }
373    else
374    {
375        /* Always parse the tables, only option is what to display */
376
377        Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
378        if (ACPI_FAILURE (Status))
379        {
380            AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
381                AcpiFormatException (Status));
382            goto Cleanup;
383        }
384
385        if (AslCompilerdebug)
386        {
387            AcpiOsPrintf ("/**** Before second load\n");
388
389            if (File)
390            {
391                NsSetupNamespaceListing (File);
392                NsDisplayNamespace ();
393            }
394            AcpiOsPrintf ("*****/\n");
395        }
396
397        /* Load namespace from names created within control methods */
398
399        AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
400            AcpiGbl_RootNode, OwnerId);
401
402        /*
403         * Cross reference the namespace here, in order to
404         * generate External() statements
405         */
406        AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
407            AcpiGbl_RootNode, OwnerId);
408
409        if (AslCompilerdebug)
410        {
411            AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
412        }
413
414        /* Find possible calls to external control methods */
415
416        AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
417
418        /*
419         * If we found any external control methods, we must reparse
420         * the entire tree with the new information (namely, the
421         * number of arguments per method)
422         */
423        if (AcpiDmGetExternalMethodCount ())
424        {
425            fprintf (stderr,
426                "\nFound %u external control methods, "
427                "reparsing with new information\n",
428                AcpiDmGetExternalMethodCount ());
429
430            /* Reparse, rebuild namespace */
431
432            AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
433            AcpiGbl_ParseOpRoot = NULL;
434            AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
435
436            AcpiGbl_RootNode                    = NULL;
437            AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
438            AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
439            AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
440            AcpiGbl_RootNodeStruct.Parent       = NULL;
441            AcpiGbl_RootNodeStruct.Child        = NULL;
442            AcpiGbl_RootNodeStruct.Peer         = NULL;
443            AcpiGbl_RootNodeStruct.Object       = NULL;
444            AcpiGbl_RootNodeStruct.Flags        = 0;
445
446            Status = AcpiNsRootInitialize ();
447
448            /* New namespace, add the external definitions first */
449
450            AcpiDmAddExternalsToNamespace ();
451
452            /* Parse the table again. No need to reload it, however */
453
454            Status = AdParseTable (Table, NULL, FALSE, FALSE);
455            if (ACPI_FAILURE (Status))
456            {
457                AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
458                    AcpiFormatException (Status));
459                goto Cleanup;
460            }
461
462            /* Cross reference the namespace again */
463
464            AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
465                AcpiGbl_RootNode, OwnerId);
466
467            AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
468                AcpiGbl_RootNode, OwnerId);
469
470            if (AslCompilerdebug)
471            {
472                AcpiOsPrintf ("/**** After second load and resource conversion\n");
473                if (File)
474                {
475                    NsSetupNamespaceListing (File);
476                    NsDisplayNamespace ();
477                }
478                AcpiOsPrintf ("*****/\n");
479
480                AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
481            }
482        }
483
484        /*
485         * Now that the namespace is finalized, we can perform namespace
486         * transforms.
487         *
488         * 1) Convert fixed-offset references to resource descriptors
489         *    to symbolic references (Note: modifies namespace)
490         */
491        AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
492
493        /* Optional displays */
494
495        if (AcpiGbl_DbOpt_Disasm)
496        {
497            /* This is the real disassembly */
498
499            AdDisplayTables (Filename, Table);
500
501            /* Dump hex table if requested (-vt) */
502
503            AcpiDmDumpDataTable (Table);
504
505            fprintf (stderr, "Disassembly completed\n");
506            if (File)
507            {
508                fprintf (stderr, "ASL Output:    %s - %u bytes\n",
509                    DisasmFilename, CmGetFileSize (File));
510            }
511
512            if (Gbl_MapfileFlag)
513            {
514                fprintf (stderr, "%14s %s - %u bytes\n",
515                    Gbl_Files[ASL_FILE_MAP_OUTPUT].ShortDescription,
516                    Gbl_Files[ASL_FILE_MAP_OUTPUT].Filename,
517                    FlGetFileSize (ASL_FILE_MAP_OUTPUT));
518            }
519        }
520    }
521
522Cleanup:
523
524    if (Table && !AcpiGbl_ForceAmlDisassembly &&!AcpiUtIsAmlTable (Table))
525    {
526        ACPI_FREE (Table);
527    }
528
529    if (File)
530    {
531        if (AslCompilerdebug) /* Display final namespace, with transforms */
532        {
533            NsSetupNamespaceListing (File);
534            NsDisplayNamespace ();
535        }
536
537        fclose (File);
538        AcpiOsRedirectOutput (stdout);
539    }
540
541    AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
542    AcpiGbl_ParseOpRoot = NULL;
543    return (Status);
544}
545
546
547/******************************************************************************
548 *
549 * FUNCTION:    AdDisassemblerHeader
550 *
551 * PARAMETERS:  Filename            - Input file for the table
552 *              TableType           - Either AML or DataTable
553 *
554 * RETURN:      None
555 *
556 * DESCRIPTION: Create the disassembler header, including ACPICA signon with
557 *              current time and date.
558 *
559 *****************************************************************************/
560
561void
562AdDisassemblerHeader (
563    char                    *Filename,
564    UINT8                   TableType)
565{
566    time_t                  Timer;
567
568
569    time (&Timer);
570
571    /* Header and input table info */
572
573    AcpiOsPrintf ("/*\n");
574    AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * "));
575
576    if (TableType == ACPI_IS_AML_TABLE)
577    {
578        if (AcpiGbl_CstyleDisassembly)
579        {
580            AcpiOsPrintf (
581                " * Disassembling to symbolic ASL+ operators\n"
582                " *\n");
583        }
584        else
585        {
586            AcpiOsPrintf (
587                " * Disassembling to non-symbolic legacy ASL operators\n"
588                " *\n");
589        }
590    }
591
592    AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
593    AcpiOsPrintf (" *\n");
594}
595
596
597/******************************************************************************
598 *
599 * FUNCTION:    AdCreateTableHeader
600 *
601 * PARAMETERS:  Filename            - Input file for the table
602 *              Table               - Pointer to the raw table
603 *
604 * RETURN:      None
605 *
606 * DESCRIPTION: Create the ASL table header, including ACPICA signon with
607 *              current time and date.
608 *
609 *****************************************************************************/
610
611static void
612AdCreateTableHeader (
613    char                    *Filename,
614    ACPI_TABLE_HEADER       *Table)
615{
616    char                    *NewFilename;
617    UINT8                   Checksum;
618
619
620    /*
621     * Print file header and dump original table header
622     */
623    AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE);
624
625    AcpiOsPrintf (" * Original Table Header:\n");
626    AcpiOsPrintf (" *     Signature        \"%4.4s\"\n",    Table->Signature);
627    AcpiOsPrintf (" *     Length           0x%8.8X (%u)\n", Table->Length, Table->Length);
628
629    /* Print and validate the revision */
630
631    AcpiOsPrintf (" *     Revision         0x%2.2X",      Table->Revision);
632
633    switch (Table->Revision)
634    {
635    case 0:
636
637        AcpiOsPrintf (" **** Invalid Revision");
638        break;
639
640    case 1:
641
642        /* Revision of DSDT controls the ACPI integer width */
643
644        if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
645        {
646            AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
647        }
648        break;
649
650    default:
651
652        break;
653    }
654    AcpiOsPrintf ("\n");
655
656    /* Print and validate the table checksum */
657
658    AcpiOsPrintf (" *     Checksum         0x%2.2X",        Table->Checksum);
659
660    Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
661    if (Checksum)
662    {
663        AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
664            (UINT8) (Table->Checksum - Checksum));
665    }
666    AcpiOsPrintf ("\n");
667
668    AcpiOsPrintf (" *     OEM ID           \"%.6s\"\n",     Table->OemId);
669    AcpiOsPrintf (" *     OEM Table ID     \"%.8s\"\n",     Table->OemTableId);
670    AcpiOsPrintf (" *     OEM Revision     0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
671    AcpiOsPrintf (" *     Compiler ID      \"%.4s\"\n",     Table->AslCompilerId);
672    AcpiOsPrintf (" *     Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
673    AcpiOsPrintf (" */\n");
674
675    /* Create AML output filename based on input filename */
676
677    if (Filename)
678    {
679        NewFilename = FlGenerateFilename (Filename, "aml");
680    }
681    else
682    {
683        NewFilename = UtStringCacheCalloc (9);
684        if (NewFilename)
685        {
686            strncat (NewFilename, Table->Signature, 4);
687            strcat (NewFilename, ".aml");
688        }
689    }
690
691    if (!NewFilename)
692    {
693        AcpiOsPrintf (" **** Could not generate AML output filename\n");
694        return;
695    }
696
697    /* Open the ASL definition block */
698
699    AcpiOsPrintf (
700        "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
701        NewFilename, Table->Signature, Table->Revision,
702        Table->OemId, Table->OemTableId, Table->OemRevision);
703}
704
705
706/******************************************************************************
707 *
708 * FUNCTION:    AdDisplayTables
709 *
710 * PARAMETERS:  Filename            - Input file for the table
711 *              Table               - Pointer to the raw table
712 *
713 * RETURN:      Status
714 *
715 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
716 *
717 *****************************************************************************/
718
719ACPI_STATUS
720AdDisplayTables (
721    char                    *Filename,
722    ACPI_TABLE_HEADER       *Table)
723{
724
725
726    if (!AcpiGbl_ParseOpRoot)
727    {
728        return (AE_NOT_EXIST);
729    }
730
731    if (!AcpiGbl_DbOpt_Verbose)
732    {
733        AdCreateTableHeader (Filename, Table);
734    }
735
736    AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
737    MpEmitMappingInfo ();
738
739    if (AcpiGbl_DbOpt_Verbose)
740    {
741        AcpiOsPrintf ("\n\nTable Header:\n");
742        AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
743            DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
744
745        AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
746        AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)),
747            Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
748    }
749
750    return (AE_OK);
751}
752
753
754/*******************************************************************************
755 *
756 * FUNCTION:    AdStoreTable
757 *
758 * PARAMETERS:  Table               - Table header
759 *              TableIndex          - Where the table index is returned
760 *
761 * RETURN:      Status and table index.
762 *
763 * DESCRIPTION: Add an ACPI table to the global table list
764 *
765 ******************************************************************************/
766
767static ACPI_STATUS
768AdStoreTable (
769    ACPI_TABLE_HEADER       *Table,
770    UINT32                  *TableIndex)
771{
772    ACPI_STATUS             Status;
773    ACPI_TABLE_DESC         *TableDesc;
774
775
776    Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc);
777    if (ACPI_FAILURE (Status))
778    {
779        return (Status);
780    }
781
782    /* Initialize added table */
783
784    AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table),
785        ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table);
786    AcpiTbValidateTable (TableDesc);
787    return (AE_OK);
788}
789
790
791/******************************************************************************
792 *
793 * FUNCTION:    AdGetLocalTables
794 *
795 * PARAMETERS:  None
796 *
797 * RETURN:      Status
798 *
799 * DESCRIPTION: Get the ACPI tables from either memory or a file
800 *
801 *****************************************************************************/
802
803ACPI_STATUS
804AdGetLocalTables (
805    void)
806{
807    ACPI_STATUS             Status;
808    ACPI_TABLE_HEADER       TableHeader;
809    ACPI_TABLE_HEADER       *NewTable;
810    UINT32                  TableIndex;
811
812
813    /* Get the DSDT via table override */
814
815    ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
816    AcpiOsTableOverride (&TableHeader, &NewTable);
817    if (!NewTable)
818    {
819        fprintf (stderr, "Could not obtain DSDT\n");
820        return (AE_NO_ACPI_TABLES);
821    }
822
823    AdWriteTable (NewTable, NewTable->Length,
824        ACPI_SIG_DSDT, NewTable->OemTableId);
825
826    /* Store DSDT in the Table Manager */
827
828    Status = AdStoreTable (NewTable, &TableIndex);
829    if (ACPI_FAILURE (Status))
830    {
831        fprintf (stderr, "Could not store DSDT\n");
832        return (AE_NO_ACPI_TABLES);
833    }
834
835    return (AE_OK);
836}
837
838
839/******************************************************************************
840 *
841 * FUNCTION:    AdParseTable
842 *
843 * PARAMETERS:  Table               - Pointer to the raw table
844 *              OwnerId             - Returned OwnerId of the table
845 *              LoadTable           - If add table to the global table list
846 *              External            - If this is an external table
847 *
848 * RETURN:      Status
849 *
850 * DESCRIPTION: Parse the DSDT.
851 *
852 *****************************************************************************/
853
854ACPI_STATUS
855AdParseTable (
856    ACPI_TABLE_HEADER       *Table,
857    ACPI_OWNER_ID           *OwnerId,
858    BOOLEAN                 LoadTable,
859    BOOLEAN                 External)
860{
861    ACPI_STATUS             Status = AE_OK;
862    ACPI_WALK_STATE         *WalkState;
863    UINT8                   *AmlStart;
864    UINT32                  AmlLength;
865    UINT32                  TableIndex;
866
867
868    if (!Table)
869    {
870        return (AE_NOT_EXIST);
871    }
872
873    /* Pass 1:  Parse everything except control method bodies */
874
875    fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
876
877    AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
878    AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
879
880    /* Create the root object */
881
882    AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp ();
883    if (!AcpiGbl_ParseOpRoot)
884    {
885        return (AE_NO_MEMORY);
886    }
887
888    /* Create and initialize a new walk state */
889
890    WalkState = AcpiDsCreateWalkState (0,
891                        AcpiGbl_ParseOpRoot, NULL, NULL);
892    if (!WalkState)
893    {
894        return (AE_NO_MEMORY);
895    }
896
897    Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
898                NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
899    if (ACPI_FAILURE (Status))
900    {
901        return (Status);
902    }
903
904    WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
905    WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
906
907    Status = AcpiPsParseAml (WalkState);
908    if (ACPI_FAILURE (Status))
909    {
910        return (Status);
911    }
912
913    /* If LoadTable is FALSE, we are parsing the last loaded table */
914
915    TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
916
917    /* Pass 2 */
918
919    if (LoadTable)
920    {
921        Status = AdStoreTable (Table, &TableIndex);
922        if (ACPI_FAILURE (Status))
923        {
924            return (Status);
925        }
926        Status = AcpiTbAllocateOwnerId (TableIndex);
927        if (ACPI_FAILURE (Status))
928        {
929            return (Status);
930        }
931        if (OwnerId)
932        {
933            Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
934            if (ACPI_FAILURE (Status))
935            {
936                return (Status);
937            }
938        }
939    }
940
941    fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
942
943    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
944    if (ACPI_FAILURE (Status))
945    {
946        return (Status);
947    }
948
949    /* No need to parse control methods of external table */
950
951    if (External)
952    {
953        return (AE_OK);
954    }
955
956    /*
957     * Pass 3: Parse control methods and link their parse trees
958     * into the main parse tree
959     */
960    fprintf (stderr,
961        "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
962    Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot);
963    fprintf (stderr, "\n");
964
965    /* Process Resource Templates */
966
967    AcpiDmFindResources (AcpiGbl_ParseOpRoot);
968
969    fprintf (stderr, "Parsing completed\n");
970    return (AE_OK);
971}
972