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