Home | History | Annotate | Line # | Download | only in common
adisasm.c revision 1.1.1.17
      1 /******************************************************************************
      2  *
      3  * Module Name: adisasm - Application-level disassembler routines
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, 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 MERCHANTABILITY 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 #include "aslcompiler.h"
     45 #include "amlcode.h"
     46 #include "acdisasm.h"
     47 #include "acdispat.h"
     48 #include "acnamesp.h"
     49 #include "acparser.h"
     50 #include "acapps.h"
     51 #include "acconvert.h"
     52 
     53 
     54 #define _COMPONENT          ACPI_TOOLS
     55         ACPI_MODULE_NAME    ("adisasm")
     56 
     57 /* Local prototypes */
     58 
     59 static ACPI_STATUS
     60 AdDoExternalFileList (
     61     char                    *Filename);
     62 
     63 static ACPI_STATUS
     64 AdDisassembleOneTable (
     65     ACPI_TABLE_HEADER       *Table,
     66     FILE                    *File,
     67     char                    *Filename,
     68     char                    *DisasmFilename);
     69 
     70 static ACPI_STATUS
     71 AdReparseOneTable (
     72     ACPI_TABLE_HEADER       *Table,
     73     FILE                    *File,
     74     ACPI_OWNER_ID           OwnerId);
     75 
     76 
     77 ACPI_TABLE_DESC             LocalTables[1];
     78 ACPI_PARSE_OBJECT           *AcpiGbl_ParseOpRoot;
     79 
     80 
     81 /* Stubs for everything except ASL compiler */
     82 
     83 #ifndef ACPI_ASL_COMPILER
     84 BOOLEAN
     85 AcpiDsIsResultUsed (
     86     ACPI_PARSE_OBJECT       *Op,
     87     ACPI_WALK_STATE         *WalkState)
     88 {
     89     return (TRUE);
     90 }
     91 
     92 ACPI_STATUS
     93 AcpiDsMethodError (
     94     ACPI_STATUS             Status,
     95     ACPI_WALK_STATE         *WalkState)
     96 {
     97     return (Status);
     98 }
     99 #endif
    100 
    101 
    102 /*******************************************************************************
    103  *
    104  * FUNCTION:    AdInitialize
    105  *
    106  * PARAMETERS:  None
    107  *
    108  * RETURN:      Status
    109  *
    110  * DESCRIPTION: ACPICA and local initialization
    111  *
    112  ******************************************************************************/
    113 
    114 ACPI_STATUS
    115 AdInitialize (
    116     void)
    117 {
    118     ACPI_STATUS             Status;
    119 
    120 
    121     /* ACPICA subsystem initialization */
    122 
    123     Status = AcpiOsInitialize ();
    124     if (ACPI_FAILURE (Status))
    125     {
    126         fprintf (stderr, "Could not initialize ACPICA subsystem: %s\n",
    127             AcpiFormatException (Status));
    128 
    129         return (Status);
    130     }
    131 
    132     Status = AcpiUtInitGlobals ();
    133     if (ACPI_FAILURE (Status))
    134     {
    135         fprintf (stderr, "Could not initialize ACPICA globals: %s\n",
    136             AcpiFormatException (Status));
    137 
    138         return (Status);
    139     }
    140 
    141     Status = AcpiUtMutexInitialize ();
    142     if (ACPI_FAILURE (Status))
    143     {
    144         fprintf (stderr, "Could not initialize ACPICA mutex objects: %s\n",
    145             AcpiFormatException (Status));
    146 
    147         return (Status);
    148     }
    149 
    150     Status = AcpiNsRootInitialize ();
    151     if (ACPI_FAILURE (Status))
    152     {
    153         fprintf (stderr, "Could not initialize ACPICA namespace: %s\n",
    154             AcpiFormatException (Status));
    155 
    156         return (Status);
    157     }
    158 
    159     /* Setup the Table Manager (cheat - there is no RSDT) */
    160 
    161     AcpiGbl_RootTableList.MaxTableCount = 1;
    162     AcpiGbl_RootTableList.CurrentTableCount = 0;
    163     AcpiGbl_RootTableList.Tables = LocalTables;
    164 
    165     return (AE_OK);
    166 }
    167 
    168 
    169 /******************************************************************************
    170  *
    171  * FUNCTION:    AdAmlDisassemble
    172  *
    173  * PARAMETERS:  Filename            - AML input filename
    174  *              OutToFile           - TRUE if output should go to a file
    175  *              Prefix              - Path prefix for output
    176  *              OutFilename         - where the filename is returned
    177  *
    178  * RETURN:      Status
    179  *
    180  * DESCRIPTION: Disassembler entry point. Disassemble an entire ACPI table.
    181  *
    182  *****************************************************************************/
    183 
    184 ACPI_STATUS
    185 AdAmlDisassemble (
    186     BOOLEAN                 OutToFile,
    187     char                    *Filename,
    188     char                    *Prefix,
    189     char                    **OutFilename)
    190 {
    191     ACPI_STATUS             Status;
    192     char                    *DisasmFilename = NULL;
    193     FILE                    *File = NULL;
    194     ACPI_TABLE_HEADER       *Table = NULL;
    195     ACPI_NEW_TABLE_DESC     *ListHead = NULL;
    196 
    197 
    198     /*
    199      * Input: AML code from either a file or via GetTables (memory or
    200      * registry)
    201      */
    202     if (Filename)
    203     {
    204         /* Get the list of all AML tables in the file */
    205 
    206         Status = AcGetAllTablesFromFile (Filename,
    207             ACPI_GET_ALL_TABLES, &ListHead);
    208         if (ACPI_FAILURE (Status))
    209         {
    210             AcpiOsPrintf ("Could not get ACPI tables from %s, %s\n",
    211                 Filename, AcpiFormatException (Status));
    212             return (Status);
    213         }
    214 
    215         /* Process any user-specified files for external objects */
    216 
    217         Status = AdDoExternalFileList (Filename);
    218         if (ACPI_FAILURE (Status))
    219         {
    220             return (Status);
    221         }
    222     }
    223     else
    224     {
    225         Status = AdGetLocalTables ();
    226         if (ACPI_FAILURE (Status))
    227         {
    228             AcpiOsPrintf ("Could not get ACPI tables, %s\n",
    229                 AcpiFormatException (Status));
    230             return (Status);
    231         }
    232 
    233         if (!AcpiGbl_DmOpt_Disasm)
    234         {
    235             return (AE_OK);
    236         }
    237 
    238         /* Obtained the local tables, just disassemble the DSDT */
    239 
    240         Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
    241         if (ACPI_FAILURE (Status))
    242         {
    243             AcpiOsPrintf ("Could not get DSDT, %s\n",
    244                 AcpiFormatException (Status));
    245             return (Status);
    246         }
    247 
    248         AcpiOsPrintf ("\nDisassembly of DSDT\n");
    249         Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
    250     }
    251 
    252     /*
    253      * Output: ASL code. Redirect to a file if requested
    254      */
    255     if (OutToFile)
    256     {
    257         /* Create/Open a disassembly output file */
    258 
    259         DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
    260         if (!DisasmFilename)
    261         {
    262             fprintf (stderr, "Could not generate output filename\n");
    263             Status = AE_ERROR;
    264             goto Cleanup;
    265         }
    266 
    267         File = fopen (DisasmFilename, "w+");
    268         if (!File)
    269         {
    270             fprintf (stderr, "Could not open output file %s\n",
    271                 DisasmFilename);
    272             Status = AE_ERROR;
    273             goto Cleanup;
    274         }
    275     }
    276 
    277     *OutFilename = DisasmFilename;
    278 
    279     /* Disassemble all AML tables within the file */
    280 
    281     while (ListHead)
    282     {
    283         Status = AdDisassembleOneTable (ListHead->Table,
    284             File, Filename, DisasmFilename);
    285         if (ACPI_FAILURE (Status))
    286         {
    287             break;
    288         }
    289 
    290         ListHead = ListHead->Next;
    291     }
    292 
    293 Cleanup:
    294 
    295     if (Table &&
    296         !AcpiGbl_ForceAmlDisassembly &&
    297         !AcpiUtIsAmlTable (Table))
    298     {
    299         ACPI_FREE (Table);
    300     }
    301 
    302     AcDeleteTableList (ListHead);
    303 
    304     if (File)
    305     {
    306         fclose (File);
    307         AcpiOsRedirectOutput (stdout);
    308     }
    309 
    310     AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    311     AcpiGbl_ParseOpRoot = NULL;
    312     return (Status);
    313 }
    314 
    315 
    316 /******************************************************************************
    317  *
    318  * FUNCTION:    AdDisassembleOneTable
    319  *
    320  * PARAMETERS:  Table               - Raw AML table
    321  *              File                - Pointer for the input file
    322  *              Filename            - AML input filename
    323  *              DisasmFilename      - Output filename
    324  *
    325  * RETURN:      Status
    326  *
    327  * DESCRIPTION: Disassemble a single ACPI table. AML or data table.
    328  *
    329  *****************************************************************************/
    330 
    331 static ACPI_STATUS
    332 AdDisassembleOneTable (
    333     ACPI_TABLE_HEADER       *Table,
    334     FILE                    *File,
    335     char                    *Filename,
    336     char                    *DisasmFilename)
    337 {
    338     ACPI_STATUS             Status;
    339     ACPI_OWNER_ID           OwnerId;
    340 
    341 
    342 #ifdef ACPI_ASL_COMPILER
    343 
    344     /*
    345      * For ASL-/ASL+ converter: replace the temporary "XXXX"
    346      * table signature with the original. This "XXXX" makes
    347      * it harder for the AML interpreter to run the badaml
    348      * (.xxx) file produced from the converter in case if
    349      * it fails to get deleted.
    350      */
    351     if (AcpiGbl_CaptureComments)
    352     {
    353         strncpy (Table->Signature, AcpiGbl_TableSig, ACPI_NAMESEG_SIZE);
    354     }
    355 #endif
    356 
    357     /* ForceAmlDisassembly means to assume the table contains valid AML */
    358 
    359     if (!AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table))
    360     {
    361         if (File)
    362         {
    363             AcpiOsRedirectOutput (File);
    364         }
    365 
    366         AdDisassemblerHeader (Filename, ACPI_IS_DATA_TABLE);
    367 
    368         /* This is a "Data Table" (non-AML table) */
    369 
    370         AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
    371             Table->Signature);
    372         AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]  "
    373             "FieldName : FieldValue\n */\n\n");
    374 
    375         AcpiDmDumpDataTable (Table);
    376         fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n",
    377             Table->Signature);
    378 
    379         if (File)
    380         {
    381             fprintf (stderr, "Formatted output:  %s - %u bytes\n",
    382                 DisasmFilename, CmGetFileSize (File));
    383         }
    384 
    385         return (AE_OK);
    386     }
    387 
    388     /* Initialize the converter output file */
    389 
    390     ASL_CV_INIT_FILETREE(Table, File);
    391 
    392     /*
    393      * This is an AML table (DSDT or SSDT).
    394      * Always parse the tables, only option is what to display
    395      */
    396     Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
    397     if (ACPI_FAILURE (Status))
    398     {
    399         AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
    400             AcpiFormatException (Status));
    401         return (Status);
    402     }
    403 
    404     /* Redirect output for code generation and debugging output */
    405 
    406     if (File)
    407     {
    408         AcpiOsRedirectOutput (File);
    409     }
    410 
    411     /* Debug output, namespace and parse tree */
    412 
    413     if (AslCompilerdebug && File)
    414     {
    415         AcpiOsPrintf ("/**** Before second load\n");
    416 
    417         NsSetupNamespaceListing (File);
    418         NsDisplayNamespace ();
    419 
    420         AcpiOsPrintf ("*****/\n");
    421     }
    422 
    423     /* Load namespace from names created within control methods */
    424 
    425     AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
    426         AcpiGbl_RootNode, OwnerId);
    427 
    428     /*
    429      * Cross reference the namespace here, in order to
    430      * generate External() statements
    431      */
    432     AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
    433         AcpiGbl_RootNode, OwnerId);
    434 
    435     if (AslCompilerdebug)
    436     {
    437         AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
    438     }
    439 
    440     /* Find possible calls to external control methods */
    441 
    442     AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
    443 
    444     /*
    445      * If we found any external control methods, we must reparse
    446      * the entire tree with the new information (namely, the
    447      * number of arguments per method)
    448      */
    449     if (AcpiDmGetUnresolvedExternalMethodCount ())
    450     {
    451         Status = AdReparseOneTable (Table, File, OwnerId);
    452         if (ACPI_FAILURE (Status))
    453         {
    454             return (Status);
    455         }
    456     }
    457 
    458     /*
    459      * Now that the namespace is finalized, we can perform namespace
    460      * transforms.
    461      *
    462      * 1) Convert fixed-offset references to resource descriptors
    463      *    to symbolic references (Note: modifies namespace)
    464      */
    465     AcpiDmConvertParseObjects (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
    466 
    467     /* Optional displays */
    468 
    469     if (AcpiGbl_DmOpt_Disasm)
    470     {
    471         /* This is the real disassembly */
    472 
    473         AdDisplayTables (Filename, Table);
    474 
    475         /* Dump hex table if requested (-vt) */
    476 
    477         AcpiDmDumpDataTable (Table);
    478 
    479         fprintf (stderr, "Disassembly completed\n");
    480         if (File)
    481         {
    482             fprintf (stderr, "ASL Output:    %s - %u bytes\n",
    483                 DisasmFilename, CmGetFileSize (File));
    484         }
    485 
    486         if (AslGbl_MapfileFlag)
    487         {
    488             fprintf (stderr, "%14s %s - %u bytes\n",
    489                 AslGbl_FileDescs[ASL_FILE_MAP_OUTPUT].ShortDescription,
    490                 AslGbl_Files[ASL_FILE_MAP_OUTPUT].Filename,
    491                 FlGetFileSize (ASL_FILE_MAP_OUTPUT));
    492         }
    493     }
    494 
    495     return (AE_OK);
    496 }
    497 
    498 
    499 /******************************************************************************
    500  *
    501  * FUNCTION:    AdReparseOneTable
    502  *
    503  * PARAMETERS:  Table               - Raw AML table
    504  *              File                - Pointer for the input file
    505  *              OwnerId             - ID for this table
    506  *
    507  * RETURN:      Status
    508  *
    509  * DESCRIPTION: Reparse a table that has already been loaded. Used to
    510  *              integrate information about external control methods.
    511  *              These methods may have been previously parsed incorrectly.
    512  *
    513  *****************************************************************************/
    514 
    515 static ACPI_STATUS
    516 AdReparseOneTable (
    517     ACPI_TABLE_HEADER       *Table,
    518     FILE                    *File,
    519     ACPI_OWNER_ID           OwnerId)
    520 {
    521     ACPI_STATUS             Status;
    522     ACPI_COMMENT_ADDR_NODE  *AddrListHead;
    523 
    524 
    525     fprintf (stderr,
    526         "\nFound %u external control methods, "
    527         "reparsing with new information\n",
    528         AcpiDmGetUnresolvedExternalMethodCount ());
    529 
    530     /* Reparse, rebuild namespace */
    531 
    532     AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    533     AcpiGbl_ParseOpRoot = NULL;
    534     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
    535 
    536     AcpiGbl_RootNode                    = NULL;
    537     AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
    538     AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
    539     AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
    540     AcpiGbl_RootNodeStruct.Parent       = NULL;
    541     AcpiGbl_RootNodeStruct.Child        = NULL;
    542     AcpiGbl_RootNodeStruct.Peer         = NULL;
    543     AcpiGbl_RootNodeStruct.Object       = NULL;
    544     AcpiGbl_RootNodeStruct.Flags        = 0;
    545 
    546     Status = AcpiNsRootInitialize ();
    547     if (ACPI_FAILURE (Status))
    548     {
    549         return (Status);
    550     }
    551 
    552     /* New namespace, add the external definitions first */
    553 
    554     AcpiDmAddExternalListToNamespace ();
    555 
    556     /* For -ca option: clear the list of comment addresses. */
    557 
    558     while (AcpiGbl_CommentAddrListHead)
    559     {
    560         AddrListHead= AcpiGbl_CommentAddrListHead;
    561         AcpiGbl_CommentAddrListHead = AcpiGbl_CommentAddrListHead->Next;
    562         AcpiOsFree(AddrListHead);
    563     }
    564 
    565     /* Parse the table again. No need to reload it, however */
    566 
    567     Status = AdParseTable (Table, NULL, FALSE, FALSE);
    568     if (ACPI_FAILURE (Status))
    569     {
    570         AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
    571             AcpiFormatException (Status));
    572         return (Status);
    573     }
    574 
    575     /* Cross reference the namespace again */
    576 
    577     AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
    578         AcpiGbl_RootNode, OwnerId);
    579 
    580     AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
    581         AcpiGbl_RootNode, OwnerId);
    582 
    583     /* Debug output - namespace and parse tree */
    584 
    585     if (AslCompilerdebug)
    586     {
    587         AcpiOsPrintf ("/**** After second load and resource conversion\n");
    588         if (File)
    589         {
    590             NsSetupNamespaceListing (File);
    591             NsDisplayNamespace ();
    592         }
    593 
    594         AcpiOsPrintf ("*****/\n");
    595         AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
    596     }
    597 
    598     return (AE_OK);
    599 }
    600 
    601 
    602 /******************************************************************************
    603  *
    604  * FUNCTION:    AdDoExternalFileList
    605  *
    606  * PARAMETERS:  Filename            - Input file for the table
    607  *
    608  * RETURN:      Status
    609  *
    610  * DESCRIPTION: Process all tables found in the -e external files list
    611  *
    612  *****************************************************************************/
    613 
    614 static ACPI_STATUS
    615 AdDoExternalFileList (
    616     char                    *Filename)
    617 {
    618     ACPI_EXTERNAL_FILE      *ExternalFileList;
    619     char                    *ExternalFilename;
    620     ACPI_NEW_TABLE_DESC     *ExternalListHead = NULL;
    621     ACPI_STATUS             Status;
    622     ACPI_STATUS             GlobalStatus = AE_OK;
    623     ACPI_OWNER_ID           OwnerId;
    624 
    625 
    626     /*
    627      * External filenames are specified on the command line like this:
    628      * Example: iasl -e file1,file2,file3 -d xxx.aml
    629      */
    630     ExternalFileList = AcpiGbl_ExternalFileList;
    631 
    632     /* Process each external file */
    633 
    634     while (ExternalFileList)
    635     {
    636         ExternalFilename = ExternalFileList->Path;
    637         if (!strcmp (ExternalFilename, Filename))
    638         {
    639             /* Next external file */
    640 
    641             ExternalFileList = ExternalFileList->Next;
    642             continue;
    643         }
    644 
    645         AcpiOsPrintf ("External object resolution file %16s\n",
    646             ExternalFilename);
    647 
    648         Status = AcGetAllTablesFromFile (
    649             ExternalFilename, ACPI_GET_ONLY_AML_TABLES, &ExternalListHead);
    650         if (ACPI_FAILURE (Status))
    651         {
    652             if (Status == AE_TYPE)
    653             {
    654                 ExternalFileList = ExternalFileList->Next;
    655                 GlobalStatus = AE_TYPE;
    656                 continue;
    657             }
    658 
    659             AcDeleteTableList (ExternalListHead);
    660             return (Status);
    661         }
    662 
    663         /* Load external tables for symbol resolution */
    664 
    665         while (ExternalListHead)
    666         {
    667             Status = AdParseTable (
    668                 ExternalListHead->Table, &OwnerId, TRUE, TRUE);
    669             if (ACPI_FAILURE (Status))
    670             {
    671                 AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
    672                     AcpiFormatException (Status));
    673                 AcDeleteTableList (ExternalListHead);
    674                 return (Status);
    675             }
    676 
    677             /*
    678              * Load namespace from names created within control methods
    679              * Set owner id of nodes in external table
    680              */
    681             AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
    682                 AcpiGbl_RootNode, OwnerId);
    683             AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    684 
    685             ExternalListHead = ExternalListHead->Next;
    686         }
    687 
    688         /* Next external file */
    689 
    690         ExternalFileList = ExternalFileList->Next;
    691     }
    692 
    693     AcDeleteTableList (ExternalListHead);
    694 
    695     if (ACPI_FAILURE (GlobalStatus))
    696     {
    697         return (GlobalStatus);
    698     }
    699 
    700     /* Clear external list generated by Scope in external tables */
    701 
    702     if (AcpiGbl_ExternalFileList)
    703     {
    704         AcpiDmClearExternalList ();
    705     }
    706 
    707     /* Load any externals defined in the optional external ref file */
    708 
    709     AcpiDmGetExternalsFromFile ();
    710     return (AE_OK);
    711 }
    712