]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/contrib/dev/acpica/common/adisasm.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / contrib / dev / acpica / common / adisasm.c
1 /******************************************************************************
2  *
3  * Module Name: adisasm - Application-level disassembler routines
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115
116
117 #include <contrib/dev/acpica/include/acpi.h>
118 #include <contrib/dev/acpica/include/accommon.h>
119 #include <contrib/dev/acpica/include/acparser.h>
120 #include <contrib/dev/acpica/include/amlcode.h>
121 #include <contrib/dev/acpica/include/acdebug.h>
122 #include <contrib/dev/acpica/include/acdisasm.h>
123 #include <contrib/dev/acpica/include/acdispat.h>
124 #include <contrib/dev/acpica/include/acnamesp.h>
125 #include <contrib/dev/acpica/include/actables.h>
126 #include <contrib/dev/acpica/include/acapps.h>
127
128 #include <stdio.h>
129 #include <time.h>
130
131
132 #define _COMPONENT          ACPI_TOOLS
133         ACPI_MODULE_NAME    ("adisasm")
134
135
136 extern int                  AslCompilerdebug;
137 extern char                 *Gbl_ExternalFilename;
138
139
140 ACPI_STATUS
141 LsDisplayNamespace (
142     void);
143
144 void
145 LsSetupNsList (
146     void                    *Handle);
147
148
149 /* Local prototypes */
150
151 void
152 AdCreateTableHeader (
153     char                    *Filename,
154     ACPI_TABLE_HEADER       *Table);
155
156 void
157 AdDisassemblerHeader (
158     char                    *Filename);
159
160 ACPI_STATUS
161 AdDeferredParse (
162     ACPI_PARSE_OBJECT       *Op,
163     UINT8                   *Aml,
164     UINT32                  AmlLength);
165
166 ACPI_STATUS
167 AdParseDeferredOps (
168     ACPI_PARSE_OBJECT       *Root);
169
170
171 /* Stubs for ASL compiler */
172
173 #ifndef ACPI_ASL_COMPILER
174 BOOLEAN
175 AcpiDsIsResultUsed (
176     ACPI_PARSE_OBJECT       *Op,
177     ACPI_WALK_STATE         *WalkState)
178 {
179     return TRUE;
180 }
181
182 ACPI_STATUS
183 AcpiDsMethodError (
184     ACPI_STATUS             Status,
185     ACPI_WALK_STATE         *WalkState)
186 {
187     return (Status);
188 }
189 #endif
190
191 ACPI_STATUS
192 AcpiNsLoadTable (
193     UINT32                  TableIndex,
194     ACPI_NAMESPACE_NODE     *Node)
195 {
196     return (AE_NOT_IMPLEMENTED);
197 }
198
199 ACPI_STATUS
200 AcpiDsRestartControlMethod (
201     ACPI_WALK_STATE         *WalkState,
202     ACPI_OPERAND_OBJECT     *ReturnDesc)
203 {
204     return (AE_OK);
205 }
206
207 void
208 AcpiDsTerminateControlMethod (
209     ACPI_OPERAND_OBJECT     *MethodDesc,
210     ACPI_WALK_STATE         *WalkState)
211 {
212     return;
213 }
214
215 ACPI_STATUS
216 AcpiDsCallControlMethod (
217     ACPI_THREAD_STATE       *Thread,
218     ACPI_WALK_STATE         *WalkState,
219     ACPI_PARSE_OBJECT       *Op)
220 {
221     return (AE_OK);
222 }
223
224 ACPI_STATUS
225 AcpiDsMethodDataInitArgs (
226     ACPI_OPERAND_OBJECT     **Params,
227     UINT32                  MaxParamCount,
228     ACPI_WALK_STATE         *WalkState)
229 {
230     return (AE_OK);
231 }
232
233
234 static ACPI_TABLE_DESC      LocalTables[1];
235 static ACPI_PARSE_OBJECT    *AcpiGbl_ParseOpRoot;
236
237
238 /*******************************************************************************
239  *
240  * FUNCTION:    AdInitialize
241  *
242  * PARAMETERS:  None
243  *
244  * RETURN:      Status
245  *
246  * DESCRIPTION: ACPICA and local initialization
247  *
248  ******************************************************************************/
249
250 ACPI_STATUS
251 AdInitialize (
252     void)
253 {
254     ACPI_STATUS             Status;
255
256
257     /* ACPI CA subsystem initialization */
258
259     Status = AcpiOsInitialize ();
260     if (ACPI_FAILURE (Status))
261     {
262         return (Status);
263     }
264
265     Status = AcpiUtInitGlobals ();
266     if (ACPI_FAILURE (Status))
267     {
268         return (Status);
269     }
270
271     Status = AcpiUtMutexInitialize ();
272     if (ACPI_FAILURE (Status))
273     {
274         return (Status);
275     }
276
277     Status = AcpiNsRootInitialize ();
278     if (ACPI_FAILURE (Status))
279     {
280         return (Status);
281     }
282
283     /* Setup the Table Manager (cheat - there is no RSDT) */
284
285     AcpiGbl_RootTableList.Size = 1;
286     AcpiGbl_RootTableList.Count = 0;
287     AcpiGbl_RootTableList.Tables = LocalTables;
288
289     return (Status);
290 }
291
292
293 /******************************************************************************
294  *
295  * FUNCTION:    AdAmlDisassemble
296  *
297  * PARAMETERS:  Filename            - AML input filename
298  *              OutToFile           - TRUE if output should go to a file
299  *              Prefix              - Path prefix for output
300  *              OutFilename         - where the filename is returned
301  *              GetAllTables        - TRUE if all tables are desired
302  *
303  * RETURN:      Status
304  *
305  * DESCRIPTION: Disassemble an entire ACPI table
306  *
307  *****************************************************************************/
308
309 ACPI_STATUS
310 AdAmlDisassemble (
311     BOOLEAN                 OutToFile,
312     char                    *Filename,
313     char                    *Prefix,
314     char                    **OutFilename,
315     BOOLEAN                 GetAllTables)
316 {
317     ACPI_STATUS             Status;
318     char                    *DisasmFilename = NULL;
319     char                    *ExternalFilename;
320     FILE                    *File = NULL;
321     ACPI_TABLE_HEADER       *Table = NULL;
322     ACPI_TABLE_HEADER       *ExternalTable;
323     ACPI_OWNER_ID           OwnerId;
324
325
326     /*
327      * Input: AML code from either a file or via GetTables (memory or
328      * registry)
329      */
330     if (Filename)
331     {
332         Status = AcpiDbGetTableFromFile (Filename, &Table);
333         if (ACPI_FAILURE (Status))
334         {
335             return Status;
336         }
337
338         /*
339          * External filenames separated by commas
340          * Example: iasl -e file1,file2,file3 -d xxx.aml
341          */
342         if (Gbl_ExternalFilename)
343         {
344             ExternalFilename = strtok (Gbl_ExternalFilename, ",");
345
346             while (ExternalFilename)
347             {
348                 Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable);
349                 if (ACPI_FAILURE (Status))
350                 {
351                     return Status;
352                 }
353
354                 /* Load external table for symbol resolution */
355
356                 if (ExternalTable)
357                 {
358                     Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
359                     if (ACPI_FAILURE (Status))
360                     {
361                         AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
362                             AcpiFormatException (Status));
363                         return Status;
364                     }
365
366                     /*
367                      * Load namespace from names created within control methods
368                      * Set owner id of nodes in external table
369                      */
370                     AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
371                         AcpiGbl_RootNode, OwnerId);
372                     AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
373                 }
374
375                 /* Next external file name */
376
377                 ExternalFilename = strtok (NULL, ",");
378             }
379
380             /* Clear external list generated by Scope in external tables */
381
382             AcpiDmClearExternalList ();
383         }
384     }
385     else
386     {
387         Status = AdGetLocalTables (Filename, GetAllTables);
388         if (ACPI_FAILURE (Status))
389         {
390             AcpiOsPrintf ("Could not get ACPI tables, %s\n",
391                 AcpiFormatException (Status));
392             return Status;
393         }
394
395         if (!AcpiGbl_DbOpt_disasm)
396         {
397             return AE_OK;
398         }
399
400         /* Obtained the local tables, just disassemble the DSDT */
401
402         Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
403         if (ACPI_FAILURE (Status))
404         {
405             AcpiOsPrintf ("Could not get DSDT, %s\n",
406                 AcpiFormatException (Status));
407             return Status;
408         }
409
410         AcpiOsPrintf ("\nDisassembly of DSDT\n");
411         Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
412     }
413
414     /*
415      * Output:  ASL code. Redirect to a file if requested
416      */
417     if (OutToFile)
418     {
419         /* Create/Open a disassembly output file */
420
421         DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
422         if (!OutFilename)
423         {
424             fprintf (stderr, "Could not generate output filename\n");
425             Status = AE_ERROR;
426             goto Cleanup;
427         }
428
429         File = fopen (DisasmFilename, "w+");
430         if (!File)
431         {
432             fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
433             Status = AE_ERROR;
434             goto Cleanup;
435         }
436
437         AcpiOsRedirectOutput (File);
438     }
439
440     *OutFilename = DisasmFilename;
441
442     if (!AcpiUtIsAmlTable (Table))
443     {
444         AdDisassemblerHeader (Filename);
445         AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
446             Table->Signature);
447         AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue\n */\n\n");
448
449         AcpiDmDumpDataTable (Table);
450         fprintf (stderr, "Acpi Data Table [%4.4s] decoded, written to \"%s\"\n",
451             Table->Signature, DisasmFilename);
452     }
453     else
454     {
455         /* Always parse the tables, only option is what to display */
456
457         Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
458         if (ACPI_FAILURE (Status))
459         {
460             AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
461                 AcpiFormatException (Status));
462             goto Cleanup;
463         }
464
465         if (AslCompilerdebug)
466         {
467             AcpiOsPrintf ("/**** Before second load\n");
468
469             LsSetupNsList (File);
470             LsDisplayNamespace ();
471             AcpiOsPrintf ("*****/\n");
472         }
473
474         /*
475          * Load namespace from names created within control methods
476          */
477         AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode, OwnerId);
478
479         /*
480          * Cross reference the namespace here, in order to generate External() statements
481          */
482         AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode, OwnerId);
483
484         if (AslCompilerdebug)
485         {
486             AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
487         }
488
489         /* Find possible calls to external control methods */
490
491         AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
492
493         /* Convert fixed-offset references to resource descriptors to symbolic references */
494
495         AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
496
497         /*
498          * If we found any external control methods, we must reparse the entire
499          * tree with the new information (namely, the number of arguments per
500          * method)
501          */
502         if (AcpiDmGetExternalMethodCount ())
503         {
504             fprintf (stderr,
505                 "\nFound %d external control methods, reparsing with new information\n",
506                 AcpiDmGetExternalMethodCount ());
507
508             /*
509              * Reparse, rebuild namespace. no need to xref namespace
510              */
511             AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
512             AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
513
514             AcpiGbl_RootNode                    = NULL;
515             AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
516             AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
517             AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
518             AcpiGbl_RootNodeStruct.Child        = NULL;
519             AcpiGbl_RootNodeStruct.Peer         = NULL;
520             AcpiGbl_RootNodeStruct.Object       = NULL;
521             AcpiGbl_RootNodeStruct.Flags        = ANOBJ_END_OF_PEER_LIST;
522
523             Status = AcpiNsRootInitialize ();
524             AcpiDmAddExternalsToNamespace ();
525
526             /* Parse table. No need to reload it, however (FALSE) */
527
528             Status = AdParseTable (Table, NULL, FALSE, FALSE);
529             if (ACPI_FAILURE (Status))
530             {
531                 AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
532                     AcpiFormatException (Status));
533                 goto Cleanup;
534             }
535
536             if (AslCompilerdebug)
537             {
538                 AcpiOsPrintf ("/**** After second load and resource conversion\n");
539                 LsSetupNsList (File);
540                 LsDisplayNamespace ();
541                 AcpiOsPrintf ("*****/\n");
542
543                 AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
544             }
545         }
546
547         /* Optional displays */
548
549         if (AcpiGbl_DbOpt_disasm)
550         {
551             AdDisplayTables (Filename, Table);
552             fprintf (stderr,
553                 "Disassembly completed, written to \"%s\"\n",
554                 DisasmFilename);
555         }
556     }
557
558 Cleanup:
559
560     if (Table && !AcpiUtIsAmlTable (Table))
561     {
562         ACPI_FREE (Table);
563     }
564
565     if (DisasmFilename)
566     {
567         ACPI_FREE (DisasmFilename);
568     }
569
570     if (OutToFile && File)
571     {
572
573 #ifdef ASL_DISASM_DEBUG
574         LsSetupNsList (File);
575         LsDisplayNamespace ();
576 #endif
577         fclose (File);
578         AcpiOsRedirectOutput (stdout);
579     }
580
581     AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
582     AcpiGbl_ParseOpRoot = NULL;
583     return (Status);
584 }
585
586
587 /******************************************************************************
588  *
589  * FUNCTION:    AdDisassemblerHeader
590  *
591  * PARAMETERS:  Filename            - Input file for the table
592  *
593  * RETURN:      None
594  *
595  * DESCRIPTION: Create the disassembler header, including ACPI CA signon with
596  *              current time and date.
597  *
598  *****************************************************************************/
599
600 void
601 AdDisassemblerHeader (
602     char                    *Filename)
603 {
604     time_t                  Timer;
605
606     time (&Timer);
607
608     /* Header and input table info */
609
610     AcpiOsPrintf ("/*\n * Intel ACPI Component Architecture\n");
611     AcpiOsPrintf (" * AML Disassembler version %8.8X\n", ACPI_CA_VERSION);
612
613     AcpiOsPrintf (" *\n * Disassembly of %s, %s", Filename, ctime (&Timer));
614     AcpiOsPrintf (" *\n");
615 }
616
617
618 /******************************************************************************
619  *
620  * FUNCTION:    AdCreateTableHeader
621  *
622  * PARAMETERS:  Filename            - Input file for the table
623  *              Table               - Pointer to the raw table
624  *
625  * RETURN:      None
626  *
627  * DESCRIPTION: Create the ASL table header, including ACPI CA signon with
628  *              current time and date.
629  *
630  *****************************************************************************/
631
632 void
633 AdCreateTableHeader (
634     char                    *Filename,
635     ACPI_TABLE_HEADER       *Table)
636 {
637     char                    *NewFilename;
638     UINT8                   Checksum;
639
640
641     /*
642      * Print file header and dump original table header
643      */
644     AdDisassemblerHeader (Filename);
645
646     AcpiOsPrintf (" *\n * Original Table Header:\n");
647     AcpiOsPrintf (" *     Signature        \"%4.4s\"\n",    Table->Signature);
648     AcpiOsPrintf (" *     Length           0x%8.8X (%u)\n", Table->Length, Table->Length);
649
650     /* Print and validate the revision */
651
652     AcpiOsPrintf (" *     Revision         0x%2.2X",      Table->Revision);
653
654     switch (Table->Revision)
655     {
656     case 0:
657         AcpiOsPrintf (" **** Invalid Revision");
658         break;
659
660     case 1:
661         /* Revision of DSDT controls the ACPI integer width */
662
663         if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
664         {
665             AcpiOsPrintf (" **** ACPI 1.0, no 64-bit math support");
666         }
667         break;
668
669     default:
670         break;
671     }
672     AcpiOsPrintf ("\n");
673
674     /* Print and validate the table checksum */
675
676     AcpiOsPrintf (" *     Checksum         0x%2.2X",        Table->Checksum);
677
678     Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
679     if (Checksum)
680     {
681         AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
682             (UINT8) (Table->Checksum - Checksum));
683     }
684     AcpiOsPrintf ("\n");
685
686     AcpiOsPrintf (" *     OEM ID           \"%.6s\"\n",     Table->OemId);
687     AcpiOsPrintf (" *     OEM Table ID     \"%.8s\"\n",     Table->OemTableId);
688     AcpiOsPrintf (" *     OEM Revision     0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
689     AcpiOsPrintf (" *     Compiler ID      \"%.4s\"\n",     Table->AslCompilerId);
690     AcpiOsPrintf (" *     Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
691     AcpiOsPrintf (" */\n");
692
693     /* Create AML output filename based on input filename */
694
695     if (Filename)
696     {
697         NewFilename = FlGenerateFilename (Filename, "aml");
698     }
699     else
700     {
701         NewFilename = ACPI_ALLOCATE_ZEROED (9);
702         strncat (NewFilename, Table->Signature, 4);
703         strcat (NewFilename, ".aml");
704     }
705
706     /* Open the ASL definition block */
707
708     AcpiOsPrintf (
709         "DefinitionBlock (\"%s\", \"%4.4s\", %hd, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
710         NewFilename, Table->Signature, Table->Revision,
711         Table->OemId, Table->OemTableId, Table->OemRevision);
712
713     ACPI_FREE (NewFilename);
714 }
715
716
717 /******************************************************************************
718  *
719  * FUNCTION:    AdDisplayTables
720  *
721  * PARAMETERS:  Filename            - Input file for the table
722  *              Table               - Pointer to the raw table
723  *
724  * RETURN:      Status
725  *
726  * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
727  *
728  *****************************************************************************/
729
730 ACPI_STATUS
731 AdDisplayTables (
732     char                    *Filename,
733     ACPI_TABLE_HEADER       *Table)
734 {
735
736
737     if (!AcpiGbl_ParseOpRoot)
738     {
739         return AE_NOT_EXIST;
740     }
741
742     if (!AcpiGbl_DbOpt_verbose)
743     {
744         AdCreateTableHeader (Filename, Table);
745     }
746
747     AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
748
749     if (AcpiGbl_DbOpt_verbose)
750     {
751         AcpiOsPrintf ("\n\nTable Header:\n");
752         AcpiUtDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
753             DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
754
755         AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
756         AcpiUtDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), Table->Length,
757             DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
758     }
759
760     return AE_OK;
761 }
762
763
764 /******************************************************************************
765  *
766  * FUNCTION:    AdDeferredParse
767  *
768  * PARAMETERS:  Op                  - Root Op of the deferred opcode
769  *              Aml                 - Pointer to the raw AML
770  *              AmlLength           - Length of the AML
771  *
772  * RETURN:      Status
773  *
774  * DESCRIPTION: Parse one deferred opcode
775  *              (Methods, operation regions, etc.)
776  *
777  *****************************************************************************/
778
779 ACPI_STATUS
780 AdDeferredParse (
781     ACPI_PARSE_OBJECT       *Op,
782     UINT8                   *Aml,
783     UINT32                  AmlLength)
784 {
785     ACPI_WALK_STATE         *WalkState;
786     ACPI_STATUS             Status;
787     ACPI_PARSE_OBJECT       *SearchOp;
788     ACPI_PARSE_OBJECT       *StartOp;
789     UINT32                  BaseAmlOffset;
790     ACPI_PARSE_OBJECT       *ExtraOp;
791
792
793     ACPI_FUNCTION_TRACE (AdDeferredParse);
794
795
796     fprintf (stderr, ".");
797
798     if (!Aml || !AmlLength)
799     {
800         return_ACPI_STATUS (AE_OK);
801     }
802
803     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing %s [%4.4s]\n",
804         Op->Common.AmlOpName, (char *) &Op->Named.Name));
805
806     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
807     if (!WalkState)
808     {
809         return_ACPI_STATUS (AE_NO_MEMORY);
810     }
811
812     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml,
813                     AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
814     if (ACPI_FAILURE (Status))
815     {
816         return_ACPI_STATUS (Status);
817     }
818
819     /* Parse the method */
820
821     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
822     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
823     Status = AcpiPsParseAml (WalkState);
824
825     /*
826      * We need to update all of the Aml offsets, since the parser thought
827      * that the method began at offset zero.  In reality, it began somewhere
828      * within the ACPI table, at the BaseAmlOffset.  Walk the entire tree that
829      * was just created and update the AmlOffset in each Op
830      */
831     BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1;
832     StartOp = (Op->Common.Value.Arg)->Common.Next;
833     SearchOp = StartOp;
834
835     /* Walk the parse tree */
836
837     while (SearchOp)
838     {
839         SearchOp->Common.AmlOffset += BaseAmlOffset;
840         SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
841     }
842
843     /*
844      * Link the newly parsed subtree into the main parse tree
845      */
846     switch (Op->Common.AmlOpcode)
847     {
848     case AML_BUFFER_OP:
849     case AML_PACKAGE_OP:
850     case AML_VAR_PACKAGE_OP:
851
852         switch (Op->Common.AmlOpcode)
853         {
854         case AML_PACKAGE_OP:
855             ExtraOp = Op->Common.Value.Arg;
856             ExtraOp = ExtraOp->Common.Next;
857             Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
858             break;
859
860         case AML_VAR_PACKAGE_OP:
861         case AML_BUFFER_OP:
862         default:
863             ExtraOp = Op->Common.Value.Arg;
864             Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
865             break;
866         }
867
868         /* Must point all parents to the main tree */
869
870         StartOp = Op;
871         SearchOp = StartOp;
872         while (SearchOp)
873         {
874             if (SearchOp->Common.Parent == ExtraOp)
875             {
876                 SearchOp->Common.Parent = Op;
877             }
878             SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
879         }
880         break;
881
882     default:
883         break;
884     }
885
886     return_ACPI_STATUS (AE_OK);
887 }
888
889
890 /******************************************************************************
891  *
892  * FUNCTION:    AdParseDeferredOps
893  *
894  * PARAMETERS:  Root                - Root of the parse tree
895  *
896  * RETURN:      Status
897  *
898  * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.)
899  *
900  *****************************************************************************/
901
902 ACPI_STATUS
903 AdParseDeferredOps (
904     ACPI_PARSE_OBJECT       *Root)
905 {
906     ACPI_PARSE_OBJECT       *Op = Root;
907     ACPI_STATUS             Status = AE_OK;
908     const ACPI_OPCODE_INFO  *OpInfo;
909
910
911     ACPI_FUNCTION_NAME (AdParseDeferredOps);
912     fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
913
914     while (Op)
915     {
916         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
917         if (!(OpInfo->Flags & AML_DEFER))
918         {
919             Op = AcpiPsGetDepthNext (Root, Op);
920             continue;
921         }
922
923         switch (Op->Common.AmlOpcode)
924         {
925         case AML_METHOD_OP:
926         case AML_BUFFER_OP:
927         case AML_PACKAGE_OP:
928         case AML_VAR_PACKAGE_OP:
929
930             Status = AdDeferredParse (Op, Op->Named.Data, Op->Named.Length);
931             if (ACPI_FAILURE (Status))
932             {
933                 return_ACPI_STATUS (Status);
934             }
935             break;
936
937         case AML_REGION_OP:
938         case AML_CREATE_QWORD_FIELD_OP:
939         case AML_CREATE_DWORD_FIELD_OP:
940         case AML_CREATE_WORD_FIELD_OP:
941         case AML_CREATE_BYTE_FIELD_OP:
942         case AML_CREATE_BIT_FIELD_OP:
943         case AML_CREATE_FIELD_OP:
944         case AML_BANK_FIELD_OP:
945
946             /* Nothing to do in these cases */
947
948             break;
949
950         default:
951             ACPI_ERROR ((AE_INFO, "Unhandled deferred opcode [%s]",
952                 Op->Common.AmlOpName));
953             break;
954         }
955
956         Op = AcpiPsGetDepthNext (Root, Op);
957     }
958
959     fprintf (stderr, "\n");
960     return Status;
961 }
962
963
964 /******************************************************************************
965  *
966  * FUNCTION:    AdGetLocalTables
967  *
968  * PARAMETERS:  Filename            - Not used
969  *              GetAllTables        - TRUE if all tables are desired
970  *
971  * RETURN:      Status
972  *
973  * DESCRIPTION: Get the ACPI tables from either memory or a file
974  *
975  *****************************************************************************/
976
977 ACPI_STATUS
978 AdGetLocalTables (
979     char                    *Filename,
980     BOOLEAN                 GetAllTables)
981 {
982     ACPI_STATUS             Status;
983     ACPI_TABLE_HEADER       TableHeader;
984     ACPI_TABLE_HEADER       *NewTable;
985     UINT32                  NumTables;
986     UINT32                  PointerSize;
987     UINT32                  TableIndex;
988
989
990     if (GetAllTables)
991     {
992         ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT);
993         AcpiOsTableOverride (&TableHeader, &NewTable);
994         if (!NewTable)
995         {
996             fprintf (stderr, "Could not obtain RSDT\n");
997             return AE_NO_ACPI_TABLES;
998         }
999         else
1000         {
1001             AdWriteTable (NewTable, NewTable->Length,
1002                 ACPI_SIG_RSDT, NewTable->OemTableId);
1003         }
1004
1005         if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT))
1006         {
1007             PointerSize = sizeof (UINT32);
1008         }
1009         else
1010         {
1011             PointerSize = sizeof (UINT64);
1012         }
1013
1014         /*
1015          * Determine the number of tables pointed to by the RSDT/XSDT.
1016          * This is defined by the ACPI Specification to be the number of
1017          * pointers contained within the RSDT/XSDT.  The size of the pointers
1018          * is architecture-dependent.
1019          */
1020         NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize;
1021         AcpiOsPrintf ("There are %d tables defined in the %4.4s\n\n",
1022             NumTables, NewTable->Signature);
1023
1024         /* Get the FADT */
1025
1026         ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT);
1027         AcpiOsTableOverride (&TableHeader, &NewTable);
1028         if (NewTable)
1029         {
1030             AdWriteTable (NewTable, NewTable->Length,
1031                 ACPI_SIG_FADT, NewTable->OemTableId);
1032         }
1033         AcpiOsPrintf ("\n");
1034
1035         /* Don't bother with FACS, it is usually all zeros */
1036     }
1037
1038     /* Always get the DSDT */
1039
1040     ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
1041     AcpiOsTableOverride (&TableHeader, &NewTable);
1042     if (NewTable)
1043     {
1044         AdWriteTable (NewTable, NewTable->Length,
1045             ACPI_SIG_DSDT, NewTable->OemTableId);
1046
1047         /* Store DSDT in the Table Manager */
1048
1049         Status = AcpiTbStoreTable (0, NewTable, NewTable->Length,
1050                     0, &TableIndex);
1051         if (ACPI_FAILURE (Status))
1052         {
1053             fprintf (stderr, "Could not store DSDT\n");
1054             return AE_NO_ACPI_TABLES;
1055         }
1056     }
1057     else
1058     {
1059         fprintf (stderr, "Could not obtain DSDT\n");
1060         return AE_NO_ACPI_TABLES;
1061     }
1062
1063 #if 0
1064     /* TBD: Future implementation */
1065
1066     AcpiOsPrintf ("\n");
1067
1068     /* Get all SSDTs */
1069
1070     ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT);
1071     do
1072     {
1073         NewTable = NULL;
1074         Status = AcpiOsTableOverride (&TableHeader, &NewTable);
1075
1076     } while (NewTable);
1077 #endif
1078
1079     return AE_OK;
1080 }
1081
1082
1083 /******************************************************************************
1084  *
1085  * FUNCTION:    AdParseTable
1086  *
1087  * PARAMETERS:  Table               - Pointer to the raw table
1088  *              OwnerId             - Returned OwnerId of the table
1089  *              LoadTable           - If add table to the global table list
1090  *              External            - If this is an external table
1091  *
1092  * RETURN:      Status
1093  *
1094  * DESCRIPTION: Parse the DSDT.
1095  *
1096  *****************************************************************************/
1097
1098 ACPI_STATUS
1099 AdParseTable (
1100     ACPI_TABLE_HEADER       *Table,
1101     ACPI_OWNER_ID           *OwnerId,
1102     BOOLEAN                 LoadTable,
1103     BOOLEAN                 External)
1104 {
1105     ACPI_STATUS             Status = AE_OK;
1106     ACPI_WALK_STATE         *WalkState;
1107     UINT8                   *AmlStart;
1108     UINT32                  AmlLength;
1109     UINT32                  TableIndex;
1110
1111
1112     if (!Table)
1113     {
1114         return AE_NOT_EXIST;
1115     }
1116
1117     /* Pass 1:  Parse everything except control method bodies */
1118
1119     fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
1120
1121     AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
1122     AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
1123
1124     /* Create the root object */
1125
1126     AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp ();
1127     if (!AcpiGbl_ParseOpRoot)
1128     {
1129         return AE_NO_MEMORY;
1130     }
1131
1132     /* Create and initialize a new walk state */
1133
1134     WalkState = AcpiDsCreateWalkState (0,
1135                         AcpiGbl_ParseOpRoot, NULL, NULL);
1136     if (!WalkState)
1137     {
1138         return (AE_NO_MEMORY);
1139     }
1140
1141     Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
1142                 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
1143     if (ACPI_FAILURE (Status))
1144     {
1145         return (Status);
1146     }
1147
1148     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
1149     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
1150
1151     Status = AcpiPsParseAml (WalkState);
1152     if (ACPI_FAILURE (Status))
1153     {
1154         return Status;
1155     }
1156
1157     /* If LoadTable is FALSE, we are parsing the last loaded table */
1158
1159     TableIndex = AcpiGbl_RootTableList.Count - 1;
1160
1161     /* Pass 2 */
1162
1163     if (LoadTable)
1164     {
1165         Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table,
1166                     Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex);
1167         if (ACPI_FAILURE (Status))
1168         {
1169             return Status;
1170         }
1171         Status = AcpiTbAllocateOwnerId (TableIndex);
1172         if (ACPI_FAILURE (Status))
1173         {
1174             return Status;
1175         }
1176         if (OwnerId)
1177         {
1178             Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
1179             if (ACPI_FAILURE (Status))
1180             {
1181                 return Status;
1182             }
1183         }
1184     }
1185
1186     fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
1187
1188     Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
1189     if (ACPI_FAILURE (Status))
1190     {
1191         return (Status);
1192     }
1193
1194     /* No need to parse control methods of external table */
1195
1196     if (External)
1197     {
1198         return AE_OK;
1199     }
1200
1201     /* Pass 3: Parse control methods and link their parse trees into the main parse tree */
1202
1203     Status = AdParseDeferredOps (AcpiGbl_ParseOpRoot);
1204
1205     /* Process Resource Templates */
1206
1207     AcpiDmFindResources (AcpiGbl_ParseOpRoot);
1208
1209     fprintf (stderr, "Parsing completed\n");
1210     return AE_OK;
1211 }
1212
1213