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