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