xref: /freebsd/sys/contrib/dev/acpica/common/adisasm.c (revision 7660b554bc59a07be0431c17e0e33815818baa69)
1 /******************************************************************************
2  *
3  * Module Name: adisasm - Application-level disassembler routines
4  *              $Revision: 58 $
5  *
6  *****************************************************************************/
7 
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, 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 "acpi.h"
119 #include "acparser.h"
120 #include "amlcode.h"
121 #include "acdebug.h"
122 #include "acdisasm.h"
123 #include "acdispat.h"
124 #include "acnamesp.h"
125 #include "acapps.h"
126 
127 #include <stdio.h>
128 #include <string.h>
129 #include <time.h>
130 
131 
132 #define _COMPONENT          ACPI_TOOLS
133         ACPI_MODULE_NAME    ("adisasm")
134 
135 
136 ACPI_PARSE_OBJECT       *AcpiGbl_ParsedNamespaceRoot;
137 
138 
139 #ifndef _ACPI_ASL_COMPILER
140 BOOLEAN
141 AcpiDsIsResultUsed (
142     ACPI_PARSE_OBJECT       *Op,
143     ACPI_WALK_STATE         *WalkState)
144 {
145     return TRUE;
146 }
147 #endif
148 
149 
150 ACPI_STATUS
151 AcpiDsRestartControlMethod (
152     ACPI_WALK_STATE         *WalkState,
153     ACPI_OPERAND_OBJECT     *ReturnDesc)
154 {
155     return (AE_OK);
156 }
157 
158 ACPI_STATUS
159 AcpiDsTerminateControlMethod (
160     ACPI_WALK_STATE         *WalkState)
161 {
162     return (AE_OK);
163 }
164 
165 ACPI_STATUS
166 AcpiDsCallControlMethod (
167     ACPI_THREAD_STATE       *Thread,
168     ACPI_WALK_STATE         *WalkState,
169     ACPI_PARSE_OBJECT       *Op)
170 {
171     return (AE_OK);
172 }
173 
174 ACPI_STATUS
175 AcpiDsMethodDataInitArgs (
176     ACPI_OPERAND_OBJECT     **Params,
177     UINT32                  MaxParamCount,
178     ACPI_WALK_STATE         *WalkState)
179 {
180     return (AE_OK);
181 }
182 
183 
184 #define FILE_SUFFIX_DISASSEMBLY     "dsl"
185 #define ACPI_TABLE_FILE_SUFFIX      ".dat"
186 char                        FilenameBuf[20];
187 
188 /******************************************************************************
189  *
190  * FUNCTION:    AfGenerateFilename
191  *
192  * PARAMETERS:
193  *
194  * RETURN:
195  *
196  * DESCRIPTION: Build an output filename from an ACPI table ID string
197  *
198  ******************************************************************************/
199 
200 char *
201 AdGenerateFilename (
202     char                    *Prefix,
203     char                    *TableId)
204 {
205     ACPI_NATIVE_UINT         i;
206     ACPI_NATIVE_UINT         j;
207 
208 
209     for (i = 0; Prefix[i]; i++)
210     {
211         FilenameBuf[i] = Prefix[i];
212     }
213 
214     FilenameBuf[i] = '_';
215     i++;
216 
217     for (j = 0; j < 8 && (TableId[j] != ' ') && (TableId[j] != 0); i++, j++)
218     {
219         FilenameBuf[i] = TableId[j];
220     }
221 
222     FilenameBuf[i] = 0;
223     strcat (FilenameBuf, ACPI_TABLE_FILE_SUFFIX);
224     return FilenameBuf;
225 }
226 
227 
228 /******************************************************************************
229  *
230  * FUNCTION:    AfWriteBuffer
231  *
232  * PARAMETERS:
233  *
234  * RETURN:
235  *
236  * DESCRIPTION: Open a file and write out a single buffer
237  *
238  ******************************************************************************/
239 
240 ACPI_NATIVE_INT
241 AdWriteBuffer (
242     char                *Filename,
243     char                *Buffer,
244     UINT32              Length)
245 {
246     FILE                *fp;
247     ACPI_NATIVE_INT     Actual;
248 
249 
250     fp = fopen (Filename, "wb");
251     if (!fp)
252     {
253         printf ("Couldn't open %s\n", Filename);
254         return -1;
255     }
256 
257     Actual = fwrite (Buffer, (size_t) Length, 1, fp);
258     fclose (fp);
259     return Actual;
260 }
261 
262 
263 /******************************************************************************
264  *
265  * FUNCTION:    AfWriteTable
266  *
267  * PARAMETERS:
268  *
269  * RETURN:
270  *
271  * DESCRIPTION: Dump the loaded tables to a file (or files)
272  *
273  ******************************************************************************/
274 
275 void
276 AdWriteTable (
277     ACPI_TABLE_HEADER       *Table,
278     UINT32                  Length,
279     char                    *TableName,
280     char                    *OemTableId)
281 {
282     char                    *Filename;
283 
284 
285     Filename = AdGenerateFilename (TableName, OemTableId);
286     AdWriteBuffer (Filename, (char *) Table, Length);
287 
288     AcpiOsPrintf ("Table [%s] written to \"%s\"\n", TableName, Filename);
289 }
290 
291 
292 /*******************************************************************************
293  *
294  * FUNCTION:    AdInitialize
295  *
296  * PARAMETERS:  None.
297  *
298  * RETURN:      Status
299  *
300  * DESCRIPTION: CA initialization
301  *
302  ******************************************************************************/
303 
304 ACPI_STATUS
305 AdInitialize (
306     void)
307 {
308     ACPI_STATUS             Status;
309 
310 
311     /* ACPI CA subsystem initialization */
312 
313     AcpiUtInitGlobals ();
314     Status = AcpiUtMutexInitialize ();
315     if (ACPI_FAILURE (Status))
316     {
317         return Status;
318     }
319 
320     Status = AcpiNsRootInitialize ();
321     return Status;
322 }
323 
324 
325 /*******************************************************************************
326  *
327  * FUNCTION:    FlGenerateFilename
328  *
329  * PARAMETERS:  InputFilename       - Original ASL source filename
330  *              Suffix              - New extension.
331  *
332  * RETURN:      New filename containing the original base + the new suffix
333  *
334  * DESCRIPTION: Generate a new filename from the ASL source filename and a new
335  *              extension.  Used to create the *.LST, *.TXT, etc. files.
336  *
337  ******************************************************************************/
338 
339 char *
340 FlGenerateFilename (
341     char                    *InputFilename,
342     char                    *Suffix)
343 {
344     char                    *Position;
345     char                    *NewFilename;
346 
347 
348     /* Copy the original filename to a new buffer */
349 
350     NewFilename = ACPI_MEM_CALLOCATE (strlen (InputFilename) + strlen (Suffix));
351     strcpy (NewFilename, InputFilename);
352 
353     /* Try to find the last dot in the filename */
354 
355     Position = strrchr (NewFilename, '.');
356     if (Position)
357     {
358         /* Tack on the new suffix */
359 
360         Position++;
361         *Position = 0;
362         strcat (Position, Suffix);
363     }
364     else
365     {
366         /* No dot, add one and then the suffix */
367 
368         strcat (NewFilename, ".");
369         strcat (NewFilename, Suffix);
370     }
371 
372     return NewFilename;
373 }
374 
375 
376 /*******************************************************************************
377  *
378  * FUNCTION:    FlSplitInputPathname
379  *
380  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
381  *                                    compiled
382  *
383  * RETURN:      Status
384  *
385  * DESCRIPTION: Split the input path into a directory and filename part
386  *              1) Directory part used to open include files
387  *              2) Filename part used to generate output filenames
388  *
389  ******************************************************************************/
390 
391 ACPI_STATUS
392 FlSplitInputPathname (
393     char                    *InputPath,
394     char                    **OutDirectoryPath,
395     char                    **OutFilename)
396 {
397     char                    *Substring;
398     char                    *DirectoryPath;
399     char                    *Filename;
400 
401 
402     *OutDirectoryPath = NULL;
403     *OutFilename = NULL;
404 
405     if (!InputPath)
406     {
407         return (AE_OK);
408     }
409 
410     /* Get the path to the input filename's directory */
411 
412     DirectoryPath = strdup (InputPath);
413     if (!DirectoryPath)
414     {
415         return (AE_NO_MEMORY);
416     }
417 
418     Substring = strrchr (DirectoryPath, '\\');
419     if (!Substring)
420     {
421         Substring = strrchr (DirectoryPath, '/');
422         if (!Substring)
423         {
424             Substring = strrchr (DirectoryPath, ':');
425         }
426     }
427 
428     if (!Substring)
429     {
430         DirectoryPath[0] = 0;
431         Filename = strdup (InputPath);
432     }
433     else
434     {
435         Filename = strdup (Substring + 1);
436         *(Substring+1) = 0;
437     }
438 
439     if (!Filename)
440     {
441         return (AE_NO_MEMORY);
442     }
443 
444     *OutDirectoryPath = DirectoryPath;
445     *OutFilename = Filename;
446 
447     return (AE_OK);
448 }
449 
450 
451 /******************************************************************************
452  *
453  * FUNCTION:    AdAmlDisassemble
454  *
455  * PARAMETERS:  OutToFile       - TRUE if output should go to a file
456  *              Filename        - AML input filename
457  *
458  * RETURN:      Status
459  *
460  * DESCRIPTION: Disassemble an entire ACPI table
461  *
462  *****************************************************************************/
463 
464 ACPI_STATUS
465 AdAmlDisassemble (
466     BOOLEAN                 OutToFile,
467     char                    *Filename,
468     char                    *Prefix,
469     char                    **OutFilename,
470     BOOLEAN                 GetAllTables)
471 {
472     ACPI_STATUS             Status;
473     char                    *DisasmFilename = NULL;
474     FILE                    *File = NULL;
475     ACPI_TABLE_HEADER       *Table;
476 
477 
478     /*
479      * Input:  AML Code from either a file,
480      *         or via GetTables (memory or registry)
481      */
482     if (Filename)
483     {
484         Status = AcpiDbGetTableFromFile (Filename, &Table);
485         if (ACPI_FAILURE (Status))
486         {
487             return Status;
488         }
489     }
490     else
491     {
492         Status = AdGetLocalTables (Filename, GetAllTables);
493         if (ACPI_FAILURE (Status))
494         {
495             AcpiOsPrintf ("Could not get ACPI tables, %s\n",
496                 AcpiFormatException (Status));
497             return Status;
498         }
499 
500         if (!AcpiGbl_DbOpt_disasm)
501         {
502             return AE_OK;
503         }
504 
505         /* Obtained the local tables, just disassmeble the DSDT */
506 
507         Table = AcpiGbl_DSDT;
508         AcpiOsPrintf ("\nDisassembly of DSDT\n");
509         Prefix = AdGenerateFilename ("dsdt", AcpiGbl_DSDT->OemTableId);
510     }
511 
512     /*
513      * Output:  ASL code.
514      *          Redirect to a file if requested
515      */
516     if (OutToFile)
517     {
518         /* Create/Open a disassembly output file */
519 
520         DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
521         if (!OutFilename)
522         {
523             fprintf (stderr, "Could not generate output filename\n");
524         }
525 
526         File = fopen (DisasmFilename, "w+");
527         if (!File)
528         {
529             fprintf (stderr, "Could not open output file\n");
530         }
531 
532         AcpiOsRedirectOutput (File);
533     }
534 
535     *OutFilename = DisasmFilename;
536 
537     /* Always parse the tables, only option is what to display */
538 
539     Status = AdParseTable (Table);
540     if (ACPI_FAILURE (Status))
541     {
542         AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
543             AcpiFormatException (Status));
544         goto Cleanup;
545     }
546 
547     /* Optional displays */
548 
549     if (AcpiGbl_DbOpt_disasm)
550     {
551         AdDisplayTables (Filename, Table);
552         fprintf (stderr, "Disassembly completed, written to \"%s\"\n", DisasmFilename);
553     }
554 
555 Cleanup:
556     if (OutToFile)
557     {
558         fclose (File);
559         AcpiOsRedirectOutput (stdout);
560     }
561 
562     AcpiPsDeleteParseTree (AcpiGbl_ParsedNamespaceRoot);
563     return AE_OK;
564 }
565 
566 
567 /******************************************************************************
568  *
569  * FUNCTION:    AdCreateTableHeader
570  *
571  * PARAMETERS:  Filename            - Input file for the table
572  *              Table               - Pointer to the raw table
573  *
574  * RETURN:      None
575  *
576  * DESCRIPTION: Create the ASL table header, including ACPI CA signon with
577  *              current time and date.
578  *
579  *****************************************************************************/
580 
581 void
582 AdCreateTableHeader (
583     char                    *Filename,
584     ACPI_TABLE_HEADER       *Table)
585 {
586     time_t                  Timer;
587 
588 
589     time (&Timer);
590 
591     AcpiOsPrintf ("/*\n * Intel ACPI Component Architecture\n");
592     AcpiOsPrintf (" * AML Disassembler version %8.8X\n", ACPI_CA_VERSION);
593     AcpiOsPrintf (" *\n * Disassembly of %s, %s */\n", Filename, ctime (&Timer));
594 
595     AcpiOsPrintf (
596         "DefinitionBlock (\"%4.4s.aml\", \"%4.4s\", %hd, \"%.6s\", \"%.8s\", %d)\n",
597         Table->Signature, Table->Signature, Table->Revision,
598         Table->OemId, Table->OemTableId, Table->OemRevision);
599 }
600 
601 
602 /******************************************************************************
603  *
604  * FUNCTION:    AdDisplayTables
605  *
606  * PARAMETERS:  Filename            - Input file for the table
607  *
608  * RETURN:      Status
609  *
610  * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
611  *
612  *****************************************************************************/
613 
614 ACPI_STATUS
615 AdDisplayTables (
616     char                    *Filename,
617     ACPI_TABLE_HEADER       *Table)
618 {
619 
620 
621     if (!AcpiGbl_ParsedNamespaceRoot)
622     {
623         return AE_NOT_EXIST;
624     }
625 
626     if (!AcpiGbl_DbOpt_verbose)
627     {
628         AdCreateTableHeader (Filename, Table);
629     }
630 
631     AcpiDmDisassemble (NULL, AcpiGbl_ParsedNamespaceRoot, ACPI_UINT32_MAX);
632 
633     if (AcpiGbl_DbOpt_verbose)
634     {
635         AcpiOsPrintf ("\n\nTable Header:\n");
636         AcpiUtDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
637             DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
638 
639         AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
640         AcpiUtDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), Table->Length,
641             DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
642     }
643 
644     return AE_OK;
645 }
646 
647 
648 /******************************************************************************
649  *
650  * FUNCTION:    AdDeferredParse
651  *
652  * PARAMETERS:  Op              - Root Op of the deferred opcode
653  *              Aml             - Pointer to the raw AML
654  *              AmlLength       - Length of the AML
655  *
656  * RETURN:      Status
657  *
658  * DESCRIPTION: Parse one deferred opcode
659  *              (Methods, operation regions, etc.)
660  *
661  *****************************************************************************/
662 
663 ACPI_STATUS
664 AdDeferredParse (
665     ACPI_PARSE_OBJECT       *Op,
666     UINT8                   *Aml,
667     UINT32                  AmlLength)
668 {
669     ACPI_WALK_STATE         *WalkState;
670     ACPI_STATUS             Status;
671     ACPI_PARSE_OBJECT       *SearchOp;
672     ACPI_PARSE_OBJECT       *StartOp;
673     UINT32                  BaseAmlOffset;
674     ACPI_PARSE_OBJECT       *ExtraOp;
675 
676 
677     ACPI_FUNCTION_TRACE ("AdDeferredParse");
678 
679 
680     fprintf (stderr, ".");
681 
682     if (!Aml || !AmlLength)
683     {
684         return_ACPI_STATUS (AE_OK);
685     }
686 
687     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing %s [%4.4s]\n",
688         Op->Common.AmlOpName, (char *) &Op->Named.Name));
689 
690     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
691     if (!WalkState)
692     {
693         return_ACPI_STATUS (AE_NO_MEMORY);
694     }
695 
696     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml,
697                     AmlLength, NULL, NULL, 1);
698     if (ACPI_FAILURE (Status))
699     {
700         return_ACPI_STATUS (Status);
701     }
702 
703     /* Parse the method */
704 
705     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
706     Status = AcpiPsParseAml (WalkState);
707 
708     /*
709      * We need to update all of the Aml offsets, since the parser thought
710      * that the method began at offset zero.  In reality, it began somewhere
711      * within the ACPI table, at the BaseAmlOffset.  Walk the entire tree that
712      * was just created and update the AmlOffset in each Op
713      */
714     BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1;
715     StartOp = (Op->Common.Value.Arg)->Common.Next;
716     SearchOp = StartOp;
717 
718     /* Walk the parse tree */
719 
720     while (SearchOp)
721     {
722         SearchOp->Common.AmlOffset += BaseAmlOffset;
723         SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
724     }
725 
726     /*
727      * Link the newly parsed subtree into the main parse tree
728      */
729     switch (Op->Common.AmlOpcode)
730     {
731     case AML_BUFFER_OP:
732     case AML_PACKAGE_OP:
733     case AML_VAR_PACKAGE_OP:
734 
735         switch (Op->Common.AmlOpcode)
736         {
737         case AML_PACKAGE_OP:
738         case AML_VAR_PACKAGE_OP:
739             ExtraOp = Op->Common.Value.Arg;
740             ExtraOp = ExtraOp->Common.Next;
741             Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
742             break;
743 
744         case AML_BUFFER_OP:
745         default:
746             ExtraOp = Op->Common.Value.Arg;
747             Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
748             break;
749         }
750 
751         /* Must point all parents to the main tree */
752 
753         StartOp = Op;
754         SearchOp = StartOp;
755         while (SearchOp)
756         {
757             if (SearchOp->Common.Parent == ExtraOp)
758             {
759                 SearchOp->Common.Parent = Op;
760             }
761             SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
762         }
763         break;
764 
765     default:
766         break;
767     }
768 
769     return_ACPI_STATUS (AE_OK);
770 }
771 
772 
773 /******************************************************************************
774  *
775  * FUNCTION:    AdParseDeferredOps
776  *
777  * PARAMETERS:  Root            - Root of the parse tree
778  *
779  * RETURN:      Status
780  *
781  * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.)
782  *
783  *****************************************************************************/
784 
785 ACPI_STATUS
786 AdParseDeferredOps (
787     ACPI_PARSE_OBJECT       *Root)
788 {
789     ACPI_PARSE_OBJECT       *Op = Root;
790     ACPI_STATUS             Status = AE_OK;
791     const ACPI_OPCODE_INFO  *OpInfo;
792 
793 
794     ACPI_FUNCTION_NAME ("AdParseDeferredOps");
795     fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
796 
797     while (Op)
798     {
799         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
800         if (!(OpInfo->Flags & AML_DEFER))
801         {
802             Op = AcpiPsGetDepthNext (Root, Op);
803             continue;
804         }
805 
806         switch (Op->Common.AmlOpcode)
807         {
808         case AML_METHOD_OP:
809         case AML_BUFFER_OP:
810         case AML_PACKAGE_OP:
811         case AML_VAR_PACKAGE_OP:
812 
813             Status = AdDeferredParse (Op, Op->Named.Data, Op->Named.Length);
814             if (ACPI_FAILURE (Status))
815             {
816                 return_ACPI_STATUS (Status);
817             }
818             break;
819 
820         case AML_REGION_OP:
821         case AML_CREATE_QWORD_FIELD_OP:
822         case AML_CREATE_DWORD_FIELD_OP:
823         case AML_CREATE_WORD_FIELD_OP:
824         case AML_CREATE_BYTE_FIELD_OP:
825         case AML_CREATE_BIT_FIELD_OP:
826         case AML_CREATE_FIELD_OP:
827 
828             /* Nothing to do in these cases */
829 
830             break;
831 
832         default:
833             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unhandled deferred opcode [%s]\n",
834                 Op->Common.AmlOpName));
835             break;
836         }
837 
838         Op = AcpiPsGetDepthNext (Root, Op);
839     }
840 
841     fprintf (stderr, "\n");
842     return Status;
843 }
844 
845 
846 /******************************************************************************
847  *
848  * FUNCTION:    AdGetLocalTables
849  *
850  * PARAMETERS:
851  *
852  * RETURN:      None
853  *
854  * DESCRIPTION: Get the ACPI tables from either memory or a file
855  *
856  *****************************************************************************/
857 
858 ACPI_STATUS
859 AdGetLocalTables (
860     char                    *Filename,
861     BOOLEAN                 GetAllTables)
862 {
863     ACPI_STATUS             Status;
864     ACPI_TABLE_HEADER       TableHeader;
865     ACPI_TABLE_HEADER       *NewTable;
866     UINT32                  NumTables;
867     UINT32                  PointerSize;
868 
869 
870     if (GetAllTables)
871     {
872         ACPI_STRNCPY (TableHeader.Signature, "RSDT", 4);
873         AcpiOsTableOverride (&TableHeader, &NewTable);
874 
875 #if ACPI_MACHINE_WIDTH != 64
876 
877         if (!ACPI_STRNCMP (NewTable->Signature, "RSDT", 4))
878         {
879             PointerSize = sizeof (UINT32);
880         }
881         else
882 #endif
883         {
884             PointerSize = sizeof (UINT64);
885         }
886 
887         /*
888          * Determine the number of tables pointed to by the RSDT/XSDT.
889          * This is defined by the ACPI Specification to be the number of
890          * pointers contained within the RSDT/XSDT.  The size of the pointers
891          * is architecture-dependent.
892          */
893         NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize;
894         AcpiOsPrintf ("There are %d tables defined in the %4.4s\n\n",
895             NumTables, NewTable->Signature);
896 
897         /* Get the FADT */
898 
899         ACPI_STRNCPY (TableHeader.Signature, "FADT", 4);
900         AcpiOsTableOverride (&TableHeader, &NewTable);
901         if (NewTable)
902         {
903             AcpiGbl_FADT = (void *) NewTable;
904             AdWriteTable (NewTable, NewTable->Length,
905                 "FADT", NewTable->OemTableId);
906         }
907         AcpiOsPrintf ("\n");
908 
909         /* Get the FACS */
910 
911         ACPI_STRNCPY (TableHeader.Signature, "FACS", 4);
912         AcpiOsTableOverride (&TableHeader, &NewTable);
913         if (NewTable)
914         {
915             AcpiGbl_FACS = (void *) NewTable;
916             AdWriteTable (NewTable, AcpiGbl_FACS->Length,
917                 "FACS", AcpiGbl_FADT->Header.OemTableId);
918         }
919         AcpiOsPrintf ("\n");
920     }
921 
922     /* Always get the DSDT */
923 
924     ACPI_STRNCPY (TableHeader.Signature, DSDT_SIG, 4);
925     AcpiOsTableOverride (&TableHeader, &NewTable);
926     if (NewTable)
927     {
928         Status = AE_OK;
929         AcpiGbl_DSDT = NewTable;
930         AdWriteTable (AcpiGbl_DSDT, AcpiGbl_DSDT->Length,
931             "DSDT", AcpiGbl_DSDT->OemTableId);
932     }
933     else
934     {
935         fprintf (stderr, "Could not obtain DSDT\n");
936         Status = AE_NO_ACPI_TABLES;
937     }
938 
939     AcpiOsPrintf ("\n");
940 
941     /* Get all SSDTs */
942 
943     ACPI_STRNCPY (TableHeader.Signature, SSDT_SIG, 4);
944     Status = AcpiOsTableOverride (&TableHeader, &NewTable);
945     if (NewTable)
946     {
947         while (NewTable)
948         {
949             Status = AcpiOsTableOverride (&TableHeader, &NewTable);
950         }
951     }
952 
953 #ifdef _HPET
954     AfGetHpet ();
955 #endif
956 
957     return AE_OK;
958 }
959 
960 /******************************************************************************
961  *
962  * FUNCTION:    AdParseTable
963  *
964  * PARAMETERS:  None
965  *
966  * RETURN:      Status
967  *
968  * DESCRIPTION: Parse the DSDT.
969  *
970  *****************************************************************************/
971 
972 ACPI_STATUS
973 AdParseTable (
974     ACPI_TABLE_HEADER       *Table)
975 {
976     ACPI_STATUS             Status = AE_OK;
977     ACPI_WALK_STATE         *WalkState;
978     ACPI_TABLE_DESC         TableDesc;
979     UINT8                   *AmlStart;
980     UINT32                  AmlLength;
981 
982 
983     if (!Table)
984     {
985         return AE_NOT_EXIST;
986     }
987 
988     /* Pass 1:  Parse everything except control method bodies */
989 
990     fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
991 
992     AmlLength  = Table->Length  - sizeof (ACPI_TABLE_HEADER);
993     AmlStart   = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
994 
995     /* Create the root object */
996 
997     AcpiGbl_ParsedNamespaceRoot = AcpiPsCreateScopeOp ();
998     if (!AcpiGbl_ParsedNamespaceRoot)
999     {
1000         return AE_NO_MEMORY;
1001     }
1002 
1003     /* Create and initialize a new walk state */
1004 
1005     WalkState = AcpiDsCreateWalkState (0,
1006                         AcpiGbl_ParsedNamespaceRoot, NULL, NULL);
1007     if (!WalkState)
1008     {
1009         return (AE_NO_MEMORY);
1010     }
1011 
1012     Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParsedNamespaceRoot,
1013                 NULL, AmlStart, AmlLength, NULL, NULL, 1);
1014     if (ACPI_FAILURE (Status))
1015     {
1016         return (Status);
1017     }
1018 
1019     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
1020 
1021     Status = AcpiPsParseAml (WalkState);
1022     if (ACPI_FAILURE (Status))
1023     {
1024         return Status;
1025     }
1026 
1027     /* Pass 2 */
1028 
1029     TableDesc.AmlStart = AmlStart;
1030     TableDesc.AmlLength = AmlLength;
1031     fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
1032 
1033     Status = AcpiNsOneCompleteParse (2, &TableDesc);
1034     if (ACPI_FAILURE (Status))
1035     {
1036         return (Status);
1037     }
1038 
1039     /* Pass 3: Parse control methods and link their parse trees into the main parse tree */
1040 
1041     Status = AdParseDeferredOps (AcpiGbl_ParsedNamespaceRoot);
1042 
1043     fprintf (stderr, "Parsing completed\n");
1044     return AE_OK;
1045 }
1046 
1047 
1048