1 /******************************************************************************
   2  *
   3  * Module Name: adisasm - Application-level disassembler routines
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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 }