adisasm.c revision 1.1.1.3 1 /******************************************************************************
2 *
3 * Module Name: adisasm - Application-level disassembler routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45 #include "acpi.h"
46 #include "accommon.h"
47 #include "acparser.h"
48 #include "amlcode.h"
49 #include "acdebug.h"
50 #include "acdisasm.h"
51 #include "acdispat.h"
52 #include "acnamesp.h"
53 #include "actables.h"
54 #include "acapps.h"
55
56 #include <stdio.h>
57 #include <time.h>
58
59
60 #define _COMPONENT ACPI_TOOLS
61 ACPI_MODULE_NAME ("adisasm")
62
63 /*
64 * Older versions of Bison won't emit this external in the generated header.
65 * Newer versions do emit the external, so we don't need to do it.
66 */
67 #ifndef ASLCOMPILER_ASLCOMPILERPARSE_H
68 extern int AslCompilerdebug;
69 #endif
70
71 ACPI_STATUS
72 NsDisplayNamespace (
73 void);
74
75 void
76 NsSetupNamespaceListing (
77 void *Handle);
78
79
80 /* Local prototypes */
81
82 static UINT32
83 AdGetFileSize (
84 FILE *File);
85
86 static void
87 AdCreateTableHeader (
88 char *Filename,
89 ACPI_TABLE_HEADER *Table);
90
91 /* Stubs for ASL compiler */
92
93 #ifndef ACPI_ASL_COMPILER
94 BOOLEAN
95 AcpiDsIsResultUsed (
96 ACPI_PARSE_OBJECT *Op,
97 ACPI_WALK_STATE *WalkState)
98 {
99 return TRUE;
100 }
101
102 ACPI_STATUS
103 AcpiDsMethodError (
104 ACPI_STATUS Status,
105 ACPI_WALK_STATE *WalkState)
106 {
107 return (Status);
108 }
109 #endif
110
111 ACPI_STATUS
112 AcpiNsLoadTable (
113 UINT32 TableIndex,
114 ACPI_NAMESPACE_NODE *Node)
115 {
116 return (AE_NOT_IMPLEMENTED);
117 }
118
119 ACPI_STATUS
120 AcpiDsRestartControlMethod (
121 ACPI_WALK_STATE *WalkState,
122 ACPI_OPERAND_OBJECT *ReturnDesc)
123 {
124 return (AE_OK);
125 }
126
127 void
128 AcpiDsTerminateControlMethod (
129 ACPI_OPERAND_OBJECT *MethodDesc,
130 ACPI_WALK_STATE *WalkState)
131 {
132 return;
133 }
134
135 ACPI_STATUS
136 AcpiDsCallControlMethod (
137 ACPI_THREAD_STATE *Thread,
138 ACPI_WALK_STATE *WalkState,
139 ACPI_PARSE_OBJECT *Op)
140 {
141 return (AE_OK);
142 }
143
144 ACPI_STATUS
145 AcpiDsMethodDataInitArgs (
146 ACPI_OPERAND_OBJECT **Params,
147 UINT32 MaxParamCount,
148 ACPI_WALK_STATE *WalkState)
149 {
150 return (AE_OK);
151 }
152
153
154 static ACPI_TABLE_DESC LocalTables[1];
155 static ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot;
156
157
158 /*******************************************************************************
159 *
160 * FUNCTION: AdGetFileSize
161 *
162 * PARAMETERS: File - Open file handle
163 *
164 * RETURN: File Size
165 *
166 * DESCRIPTION: Get current file size. Uses seek-to-EOF. File must be open.
167 *
168 ******************************************************************************/
169
170 static UINT32
171 AdGetFileSize (
172 FILE *File)
173 {
174 UINT32 FileSize;
175 long Offset;
176
177
178 Offset = ftell (File);
179
180 fseek (File, 0, SEEK_END);
181 FileSize = (UINT32) ftell (File);
182
183 /* Restore file pointer */
184
185 fseek (File, Offset, SEEK_SET);
186 return (FileSize);
187 }
188
189
190 /*******************************************************************************
191 *
192 * FUNCTION: AdInitialize
193 *
194 * PARAMETERS: None
195 *
196 * RETURN: Status
197 *
198 * DESCRIPTION: ACPICA and local initialization
199 *
200 ******************************************************************************/
201
202 ACPI_STATUS
203 AdInitialize (
204 void)
205 {
206 ACPI_STATUS Status;
207
208
209 /* ACPI CA subsystem initialization */
210
211 Status = AcpiOsInitialize ();
212 if (ACPI_FAILURE (Status))
213 {
214 return (Status);
215 }
216
217 Status = AcpiUtInitGlobals ();
218 if (ACPI_FAILURE (Status))
219 {
220 return (Status);
221 }
222
223 Status = AcpiUtMutexInitialize ();
224 if (ACPI_FAILURE (Status))
225 {
226 return (Status);
227 }
228
229 Status = AcpiNsRootInitialize ();
230 if (ACPI_FAILURE (Status))
231 {
232 return (Status);
233 }
234
235 /* Setup the Table Manager (cheat - there is no RSDT) */
236
237 AcpiGbl_RootTableList.MaxTableCount = 1;
238 AcpiGbl_RootTableList.CurrentTableCount = 0;
239 AcpiGbl_RootTableList.Tables = LocalTables;
240
241 return (Status);
242 }
243
244
245 /******************************************************************************
246 *
247 * FUNCTION: AdAmlDisassemble
248 *
249 * PARAMETERS: Filename - AML input filename
250 * OutToFile - TRUE if output should go to a file
251 * Prefix - Path prefix for output
252 * OutFilename - where the filename is returned
253 * GetAllTables - TRUE if all tables are desired
254 *
255 * RETURN: Status
256 *
257 * DESCRIPTION: Disassemble an entire ACPI table
258 *
259 *****************************************************************************/
260
261 ACPI_STATUS
262 AdAmlDisassemble (
263 BOOLEAN OutToFile,
264 char *Filename,
265 char *Prefix,
266 char **OutFilename,
267 BOOLEAN GetAllTables)
268 {
269 ACPI_STATUS Status;
270 char *DisasmFilename = NULL;
271 char *ExternalFilename;
272 ACPI_EXTERNAL_FILE *ExternalFileList = AcpiGbl_ExternalFileList;
273 FILE *File = NULL;
274 ACPI_TABLE_HEADER *Table = NULL;
275 ACPI_TABLE_HEADER *ExternalTable;
276 ACPI_OWNER_ID OwnerId;
277
278
279 /*
280 * Input: AML code from either a file or via GetTables (memory or
281 * registry)
282 */
283 if (Filename)
284 {
285 Status = AcpiDbGetTableFromFile (Filename, &Table);
286 if (ACPI_FAILURE (Status))
287 {
288 return (Status);
289 }
290
291 /*
292 * External filenames separated by commas
293 * Example: iasl -e file1,file2,file3 -d xxx.aml
294 */
295 while (ExternalFileList)
296 {
297 ExternalFilename = ExternalFileList->Path;
298 if (!ACPI_STRCMP (ExternalFilename, Filename))
299 {
300 /* Next external file */
301
302 ExternalFileList = ExternalFileList->Next;
303 continue;
304 }
305
306 Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable);
307 if (ACPI_FAILURE (Status))
308 {
309 return (Status);
310 }
311
312 /* Load external table for symbol resolution */
313
314 if (ExternalTable)
315 {
316 Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
317 if (ACPI_FAILURE (Status))
318 {
319 AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
320 AcpiFormatException (Status));
321 return (Status);
322 }
323
324 /*
325 * Load namespace from names created within control methods
326 * Set owner id of nodes in external table
327 */
328 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
329 AcpiGbl_RootNode, OwnerId);
330 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
331 }
332
333 /* Next external file */
334
335 ExternalFileList = ExternalFileList->Next;
336 }
337
338 /* Clear external list generated by Scope in external tables */
339
340 if (AcpiGbl_ExternalFileList)
341 {
342 AcpiDmClearExternalList ();
343 }
344
345 /* Load any externals defined in the optional external ref file */
346
347 AcpiDmGetExternalsFromFile ();
348 }
349 else
350 {
351 Status = AdGetLocalTables (Filename, GetAllTables);
352 if (ACPI_FAILURE (Status))
353 {
354 AcpiOsPrintf ("Could not get ACPI tables, %s\n",
355 AcpiFormatException (Status));
356 return (Status);
357 }
358
359 if (!AcpiGbl_DbOpt_disasm)
360 {
361 return (AE_OK);
362 }
363
364 /* Obtained the local tables, just disassemble the DSDT */
365
366 Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
367 if (ACPI_FAILURE (Status))
368 {
369 AcpiOsPrintf ("Could not get DSDT, %s\n",
370 AcpiFormatException (Status));
371 return (Status);
372 }
373
374 AcpiOsPrintf ("\nDisassembly of DSDT\n");
375 Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
376 }
377
378 /*
379 * Output: ASL code. Redirect to a file if requested
380 */
381 if (OutToFile)
382 {
383 /* Create/Open a disassembly output file */
384
385 DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
386 if (!OutFilename)
387 {
388 fprintf (stderr, "Could not generate output filename\n");
389 Status = AE_ERROR;
390 goto Cleanup;
391 }
392
393 File = fopen (DisasmFilename, "w+");
394 if (!File)
395 {
396 fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
397 Status = AE_ERROR;
398 goto Cleanup;
399 }
400
401 AcpiOsRedirectOutput (File);
402 }
403
404 *OutFilename = DisasmFilename;
405
406 if (!AcpiUtIsAmlTable (Table))
407 {
408 AdDisassemblerHeader (Filename);
409 AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
410 Table->Signature);
411 AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] "
412 "FieldName : FieldValue\n */\n\n");
413
414 AcpiDmDumpDataTable (Table);
415 fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n",
416 Table->Signature);
417 fprintf (stderr, "Formatted output: %s - %u bytes\n",
418 DisasmFilename, AdGetFileSize (File));
419 }
420 else
421 {
422 /* Always parse the tables, only option is what to display */
423
424 Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
425 if (ACPI_FAILURE (Status))
426 {
427 AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
428 AcpiFormatException (Status));
429 goto Cleanup;
430 }
431
432 if (AslCompilerdebug)
433 {
434 AcpiOsPrintf ("/**** Before second load\n");
435
436 NsSetupNamespaceListing (File);
437 NsDisplayNamespace ();
438 AcpiOsPrintf ("*****/\n");
439 }
440
441 /* Load namespace from names created within control methods */
442
443 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
444 AcpiGbl_RootNode, OwnerId);
445
446 /*
447 * Cross reference the namespace here, in order to
448 * generate External() statements
449 */
450 AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
451 AcpiGbl_RootNode, OwnerId);
452
453 if (AslCompilerdebug)
454 {
455 AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
456 }
457
458 /* Find possible calls to external control methods */
459
460 AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
461
462 /*
463 * If we found any external control methods, we must reparse
464 * the entire tree with the new information (namely, the
465 * number of arguments per method)
466 */
467 if (AcpiDmGetExternalMethodCount ())
468 {
469 fprintf (stderr,
470 "\nFound %u external control methods, "
471 "reparsing with new information\n",
472 AcpiDmGetExternalMethodCount ());
473
474 /* Reparse, rebuild namespace. no need to xref namespace */
475
476 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
477 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
478
479 AcpiGbl_RootNode = NULL;
480 AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
481 AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
482 AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE;
483 AcpiGbl_RootNodeStruct.Parent = NULL;
484 AcpiGbl_RootNodeStruct.Child = NULL;
485 AcpiGbl_RootNodeStruct.Peer = NULL;
486 AcpiGbl_RootNodeStruct.Object = NULL;
487 AcpiGbl_RootNodeStruct.Flags = 0;
488
489 Status = AcpiNsRootInitialize ();
490 AcpiDmAddExternalsToNamespace ();
491
492 /* Parse the table again. No need to reload it, however */
493
494 Status = AdParseTable (Table, NULL, FALSE, FALSE);
495 if (ACPI_FAILURE (Status))
496 {
497 AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
498 AcpiFormatException (Status));
499 goto Cleanup;
500 }
501
502 if (AslCompilerdebug)
503 {
504 AcpiOsPrintf ("/**** After second load and resource conversion\n");
505 NsSetupNamespaceListing (File);
506 NsDisplayNamespace ();
507 AcpiOsPrintf ("*****/\n");
508
509 AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
510 }
511 }
512
513 /*
514 * Now that the namespace is finalized, we can perform namespace
515 * transforms.
516 *
517 * 1) Convert fixed-offset references to resource descriptors
518 * to symbolic references (Note: modifies namespace)
519 */
520 AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
521
522 /* Optional displays */
523
524 if (AcpiGbl_DbOpt_disasm)
525 {
526 /* This is the real disassembly */
527
528 AdDisplayTables (Filename, Table);
529
530 /* Dump hex table if requested (-vt) */
531
532 AcpiDmDumpDataTable (Table);
533
534 fprintf (stderr, "Disassembly completed\n");
535 fprintf (stderr, "ASL Output: %s - %u bytes\n",
536 DisasmFilename, AdGetFileSize (File));
537 }
538 }
539
540 Cleanup:
541
542 if (Table && !AcpiUtIsAmlTable (Table))
543 {
544 ACPI_FREE (Table);
545 }
546
547 if (OutToFile && File)
548 {
549 if (AslCompilerdebug) /* Display final namespace, with transforms */
550 {
551 NsSetupNamespaceListing (File);
552 NsDisplayNamespace ();
553 }
554
555 fclose (File);
556 AcpiOsRedirectOutput (stdout);
557 }
558
559 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
560 AcpiGbl_ParseOpRoot = NULL;
561 return (Status);
562 }
563
564
565 /******************************************************************************
566 *
567 * FUNCTION: AdDisassemblerHeader
568 *
569 * PARAMETERS: Filename - Input file for the table
570 *
571 * RETURN: None
572 *
573 * DESCRIPTION: Create the disassembler header, including ACPI CA signon with
574 * current time and date.
575 *
576 *****************************************************************************/
577
578 void
579 AdDisassemblerHeader (
580 char *Filename)
581 {
582 time_t Timer;
583
584 time (&Timer);
585
586 /* Header and input table info */
587
588 AcpiOsPrintf ("/*\n");
589 AcpiOsPrintf (ACPI_COMMON_HEADER ("AML Disassembler", " * "));
590
591 AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
592 AcpiOsPrintf (" *\n");
593 }
594
595
596 /******************************************************************************
597 *
598 * FUNCTION: AdCreateTableHeader
599 *
600 * PARAMETERS: Filename - Input file for the table
601 * Table - Pointer to the raw table
602 *
603 * RETURN: None
604 *
605 * DESCRIPTION: Create the ASL table header, including ACPI CA signon with
606 * current time and date.
607 *
608 *****************************************************************************/
609
610 static void
611 AdCreateTableHeader (
612 char *Filename,
613 ACPI_TABLE_HEADER *Table)
614 {
615 char *NewFilename;
616 UINT8 Checksum;
617
618
619 /*
620 * Print file header and dump original table header
621 */
622 AdDisassemblerHeader (Filename);
623
624 AcpiOsPrintf (" * Original Table Header:\n");
625 AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature);
626 AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length);
627
628 /* Print and validate the revision */
629
630 AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision);
631
632 switch (Table->Revision)
633 {
634 case 0:
635
636 AcpiOsPrintf (" **** Invalid Revision");
637 break;
638
639 case 1:
640
641 /* Revision of DSDT controls the ACPI integer width */
642
643 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
644 {
645 AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
646 }
647 break;
648
649 default:
650
651 break;
652 }
653 AcpiOsPrintf ("\n");
654
655 /* Print and validate the table checksum */
656
657 AcpiOsPrintf (" * Checksum 0x%2.2X", Table->Checksum);
658
659 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
660 if (Checksum)
661 {
662 AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
663 (UINT8) (Table->Checksum - Checksum));
664 }
665 AcpiOsPrintf ("\n");
666
667 AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId);
668 AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId);
669 AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
670 AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId);
671 AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
672 AcpiOsPrintf (" */\n");
673
674 /* Create AML output filename based on input filename */
675
676 if (Filename)
677 {
678 NewFilename = FlGenerateFilename (Filename, "aml");
679 }
680 else
681 {
682 NewFilename = ACPI_ALLOCATE_ZEROED (9);
683 strncat (NewFilename, Table->Signature, 4);
684 strcat (NewFilename, ".aml");
685 }
686
687 /* Open the ASL definition block */
688
689 AcpiOsPrintf (
690 "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
691 NewFilename, Table->Signature, Table->Revision,
692 Table->OemId, Table->OemTableId, Table->OemRevision);
693
694 ACPI_FREE (NewFilename);
695 }
696
697
698 /******************************************************************************
699 *
700 * FUNCTION: AdDisplayTables
701 *
702 * PARAMETERS: Filename - Input file for the table
703 * Table - Pointer to the raw table
704 *
705 * RETURN: Status
706 *
707 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
708 *
709 *****************************************************************************/
710
711 ACPI_STATUS
712 AdDisplayTables (
713 char *Filename,
714 ACPI_TABLE_HEADER *Table)
715 {
716
717
718 if (!AcpiGbl_ParseOpRoot)
719 {
720 return (AE_NOT_EXIST);
721 }
722
723 if (!AcpiGbl_DbOpt_verbose)
724 {
725 AdCreateTableHeader (Filename, Table);
726 }
727
728 AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
729
730 if (AcpiGbl_DbOpt_verbose)
731 {
732 AcpiOsPrintf ("\n\nTable Header:\n");
733 AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
734 DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
735
736 AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
737 AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)),
738 Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
739 }
740
741 return (AE_OK);
742 }
743
744
745 /******************************************************************************
746 *
747 * FUNCTION: AdGetLocalTables
748 *
749 * PARAMETERS: Filename - Not used
750 * GetAllTables - TRUE if all tables are desired
751 *
752 * RETURN: Status
753 *
754 * DESCRIPTION: Get the ACPI tables from either memory or a file
755 *
756 *****************************************************************************/
757
758 ACPI_STATUS
759 AdGetLocalTables (
760 char *Filename,
761 BOOLEAN GetAllTables)
762 {
763 ACPI_STATUS Status;
764 ACPI_TABLE_HEADER TableHeader;
765 ACPI_TABLE_HEADER *NewTable;
766 UINT32 NumTables;
767 UINT32 PointerSize;
768 UINT32 TableIndex;
769
770
771 if (GetAllTables)
772 {
773 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT);
774 AcpiOsTableOverride (&TableHeader, &NewTable);
775 if (!NewTable)
776 {
777 fprintf (stderr, "Could not obtain RSDT\n");
778 return (AE_NO_ACPI_TABLES);
779 }
780 else
781 {
782 AdWriteTable (NewTable, NewTable->Length,
783 ACPI_SIG_RSDT, NewTable->OemTableId);
784 }
785
786 if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT))
787 {
788 PointerSize = sizeof (UINT32);
789 }
790 else
791 {
792 PointerSize = sizeof (UINT64);
793 }
794
795 /*
796 * Determine the number of tables pointed to by the RSDT/XSDT.
797 * This is defined by the ACPI Specification to be the number of
798 * pointers contained within the RSDT/XSDT. The size of the pointers
799 * is architecture-dependent.
800 */
801 NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize;
802 AcpiOsPrintf ("There are %u tables defined in the %4.4s\n\n",
803 NumTables, NewTable->Signature);
804
805 /* Get the FADT */
806
807 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT);
808 AcpiOsTableOverride (&TableHeader, &NewTable);
809 if (NewTable)
810 {
811 AdWriteTable (NewTable, NewTable->Length,
812 ACPI_SIG_FADT, NewTable->OemTableId);
813 }
814 AcpiOsPrintf ("\n");
815
816 /* Don't bother with FACS, it is usually all zeros */
817 }
818
819 /* Always get the DSDT */
820
821 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
822 AcpiOsTableOverride (&TableHeader, &NewTable);
823 if (NewTable)
824 {
825 AdWriteTable (NewTable, NewTable->Length,
826 ACPI_SIG_DSDT, NewTable->OemTableId);
827
828 /* Store DSDT in the Table Manager */
829
830 Status = AcpiTbStoreTable (0, NewTable, NewTable->Length,
831 0, &TableIndex);
832 if (ACPI_FAILURE (Status))
833 {
834 fprintf (stderr, "Could not store DSDT\n");
835 return (AE_NO_ACPI_TABLES);
836 }
837 }
838 else
839 {
840 fprintf (stderr, "Could not obtain DSDT\n");
841 return (AE_NO_ACPI_TABLES);
842 }
843
844 #if 0
845 /* TBD: Future implementation */
846
847 AcpiOsPrintf ("\n");
848
849 /* Get all SSDTs */
850
851 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT);
852 do
853 {
854 NewTable = NULL;
855 Status = AcpiOsTableOverride (&TableHeader, &NewTable);
856
857 } while (NewTable);
858 #endif
859
860 return (AE_OK);
861 }
862
863
864 /******************************************************************************
865 *
866 * FUNCTION: AdParseTable
867 *
868 * PARAMETERS: Table - Pointer to the raw table
869 * OwnerId - Returned OwnerId of the table
870 * LoadTable - If add table to the global table list
871 * External - If this is an external table
872 *
873 * RETURN: Status
874 *
875 * DESCRIPTION: Parse the DSDT.
876 *
877 *****************************************************************************/
878
879 ACPI_STATUS
880 AdParseTable (
881 ACPI_TABLE_HEADER *Table,
882 ACPI_OWNER_ID *OwnerId,
883 BOOLEAN LoadTable,
884 BOOLEAN External)
885 {
886 ACPI_STATUS Status = AE_OK;
887 ACPI_WALK_STATE *WalkState;
888 UINT8 *AmlStart;
889 UINT32 AmlLength;
890 UINT32 TableIndex;
891
892
893 if (!Table)
894 {
895 return (AE_NOT_EXIST);
896 }
897
898 /* Pass 1: Parse everything except control method bodies */
899
900 fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
901
902 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
903 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
904
905 /* Create the root object */
906
907 AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp ();
908 if (!AcpiGbl_ParseOpRoot)
909 {
910 return (AE_NO_MEMORY);
911 }
912
913 /* Create and initialize a new walk state */
914
915 WalkState = AcpiDsCreateWalkState (0,
916 AcpiGbl_ParseOpRoot, NULL, NULL);
917 if (!WalkState)
918 {
919 return (AE_NO_MEMORY);
920 }
921
922 Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
923 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
924 if (ACPI_FAILURE (Status))
925 {
926 return (Status);
927 }
928
929 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
930 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
931
932 Status = AcpiPsParseAml (WalkState);
933 if (ACPI_FAILURE (Status))
934 {
935 return (Status);
936 }
937
938 /* If LoadTable is FALSE, we are parsing the last loaded table */
939
940 TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
941
942 /* Pass 2 */
943
944 if (LoadTable)
945 {
946 Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table,
947 Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex);
948 if (ACPI_FAILURE (Status))
949 {
950 return (Status);
951 }
952 Status = AcpiTbAllocateOwnerId (TableIndex);
953 if (ACPI_FAILURE (Status))
954 {
955 return (Status);
956 }
957 if (OwnerId)
958 {
959 Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
960 if (ACPI_FAILURE (Status))
961 {
962 return (Status);
963 }
964 }
965 }
966
967 fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
968
969 Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
970 if (ACPI_FAILURE (Status))
971 {
972 return (Status);
973 }
974
975 /* No need to parse control methods of external table */
976
977 if (External)
978 {
979 return (AE_OK);
980 }
981
982 /* Pass 3: Parse control methods and link their parse trees into the main parse tree */
983
984 fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
985 Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot);
986 fprintf (stderr, "\n");
987
988 /* Process Resource Templates */
989
990 AcpiDmFindResources (AcpiGbl_ParseOpRoot);
991
992 fprintf (stderr, "Parsing completed\n");
993 return (AE_OK);
994 }
995