Path: blob/main/sys/contrib/dev/acpica/common/dmextern.c
48375 views
/******************************************************************************1*2* Module Name: dmextern - Support for External() ASL statements3*4*****************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/amlcode.h>154#include <contrib/dev/acpica/include/acnamesp.h>155#include <contrib/dev/acpica/include/acdisasm.h>156#include <contrib/dev/acpica/compiler/aslcompiler.h>157#include <stdio.h>158#include <errno.h>159160161/*162* This module is used for application-level code (iASL disassembler) only.163*164* It contains the code to create and emit any necessary External() ASL165* statements for the module being disassembled.166*/167#define _COMPONENT ACPI_CA_DISASSEMBLER168ACPI_MODULE_NAME ("dmextern")169170171/*172* This table maps ACPI_OBJECT_TYPEs to the corresponding ASL173* ObjectTypeKeyword. Used to generate typed external declarations174*/175static const char *AcpiGbl_DmTypeNames[] =176{177/* 00 */ ", UnknownObj", /* Type ANY */178/* 01 */ ", IntObj",179/* 02 */ ", StrObj",180/* 03 */ ", BuffObj",181/* 04 */ ", PkgObj",182/* 05 */ ", FieldUnitObj",183/* 06 */ ", DeviceObj",184/* 07 */ ", EventObj",185/* 08 */ ", MethodObj",186/* 09 */ ", MutexObj",187/* 10 */ ", OpRegionObj",188/* 11 */ ", PowerResObj",189/* 12 */ ", ProcessorObj",190/* 13 */ ", ThermalZoneObj",191/* 14 */ ", BuffFieldObj",192/* 15 */ ", DDBHandleObj",193/* 16 */ "", /* Debug object */194/* 17 */ ", FieldUnitObj",195/* 18 */ ", FieldUnitObj",196/* 19 */ ", FieldUnitObj"197};198199#define METHOD_SEPARATORS " \t,()\n"200201static const char *ExternalConflictMessage =202" // Conflicts with a later declaration";203204205/* Local prototypes */206207static const char *208AcpiDmGetObjectTypeName (209ACPI_OBJECT_TYPE Type);210211static char *212AcpiDmNormalizeParentPrefix (213ACPI_PARSE_OBJECT *Op,214char *Path);215216static ACPI_STATUS217AcpiDmGetExternalAndInternalPath (218ACPI_NAMESPACE_NODE *Node,219char **ExternalPath,220char **InternalPath);221222static ACPI_STATUS223AcpiDmRemoveRootPrefix (224char **Path);225226static void227AcpiDmAddPathToExternalList (228char *Path,229UINT8 Type,230UINT32 Value,231UINT16 Flags);232233static ACPI_STATUS234AcpiDmCreateNewExternal (235char *ExternalPath,236char *InternalPath,237UINT8 Type,238UINT32 Value,239UINT16 Flags);240241static void242AcpiDmCheckForExternalConflict (243char *Path);244245static ACPI_STATUS246AcpiDmResolveExternal (247char *Path,248UINT8 Type,249ACPI_NAMESPACE_NODE **Node);250251252static void253AcpiDmConflictingDeclaration (254char *Path);255256257/*******************************************************************************258*259* FUNCTION: AcpiDmGetObjectTypeName260*261* PARAMETERS: Type - An ACPI_OBJECT_TYPE262*263* RETURN: Pointer to a string264*265* DESCRIPTION: Map an object type to the ASL object type string.266*267******************************************************************************/268269static const char *270AcpiDmGetObjectTypeName (271ACPI_OBJECT_TYPE Type)272{273274if (Type == ACPI_TYPE_LOCAL_SCOPE)275{276Type = ACPI_TYPE_DEVICE;277}278else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)279{280return ("");281}282283return (AcpiGbl_DmTypeNames[Type]);284}285286287/*******************************************************************************288*289* FUNCTION: AcpiDmNormalizeParentPrefix290*291* PARAMETERS: Op - Parse op292* Path - Path with parent prefix293*294* RETURN: The full pathname to the object (from the namespace root)295*296* DESCRIPTION: Returns the full pathname of a path with parent prefix297* The caller must free the fullpath returned.298*299******************************************************************************/300301static char *302AcpiDmNormalizeParentPrefix (303ACPI_PARSE_OBJECT *Op,304char *Path)305{306ACPI_NAMESPACE_NODE *Node;307char *Fullpath;308char *ParentPath;309ACPI_SIZE Length;310UINT32 Index = 0;311312313if (!Op)314{315return (NULL);316}317318/* Search upwards in the parse tree until we reach the next namespace node */319320Op = Op->Common.Parent;321while (Op)322{323if (Op->Common.Node)324{325break;326}327328Op = Op->Common.Parent;329}330331if (!Op)332{333return (NULL);334}335336/*337* Find the actual parent node for the reference:338* Remove all carat prefixes from the input path.339* There may be multiple parent prefixes (For example, ^^^M000)340*/341Node = Op->Common.Node;342while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))343{344Node = Node->Parent;345Path++;346}347348if (!Node)349{350return (NULL);351}352353/* Get the full pathname for the parent node */354355ParentPath = AcpiNsGetExternalPathname (Node);356if (!ParentPath)357{358return (NULL);359}360361Length = (strlen (ParentPath) + strlen (Path) + 1);362if (ParentPath[1])363{364/*365* If ParentPath is not just a simple '\', increment the length366* for the required dot separator (ParentPath.Path)367*/368Length++;369370/* For External() statements, we do not want a leading '\' */371372if (*ParentPath == AML_ROOT_PREFIX)373{374Index = 1;375}376}377378Fullpath = ACPI_ALLOCATE_ZEROED (Length);379if (!Fullpath)380{381goto Cleanup;382}383384/*385* Concatenate parent fullpath and path. For example,386* parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"387*388* Copy the parent path389*/390strcpy (Fullpath, &ParentPath[Index]);391392/*393* Add dot separator394* (don't need dot if parent fullpath is a single backslash)395*/396if (ParentPath[1])397{398strcat (Fullpath, ".");399}400401/* Copy child path (carat parent prefix(es) were skipped above) */402403strcat (Fullpath, Path);404405Cleanup:406ACPI_FREE (ParentPath);407return (Fullpath);408}409410411/*******************************************************************************412*413* FUNCTION: AcpiDmAddToExternalFileList414*415* PARAMETERS: PathList - Single path or list separated by comma416*417* RETURN: None418*419* DESCRIPTION: Add external files to global list420*421******************************************************************************/422423ACPI_STATUS424AcpiDmAddToExternalFileList (425char *Pathname)426{427ACPI_EXTERNAL_FILE *ExternalFile;428char *LocalPathname;429430431if (!Pathname)432{433return (AE_OK);434}435436LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);437if (!LocalPathname)438{439return (AE_NO_MEMORY);440}441442ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));443if (!ExternalFile)444{445ACPI_FREE (LocalPathname);446return (AE_NO_MEMORY);447}448449/* Take a copy of the file pathname */450451strcpy (LocalPathname, Pathname);452ExternalFile->Path = LocalPathname;453454if (AcpiGbl_ExternalFileList)455{456ExternalFile->Next = AcpiGbl_ExternalFileList;457}458459AcpiGbl_ExternalFileList = ExternalFile;460return (AE_OK);461}462463464/*******************************************************************************465*466* FUNCTION: AcpiDmClearExternalFileList467*468* PARAMETERS: None469*470* RETURN: None471*472* DESCRIPTION: Clear the external file list473*474******************************************************************************/475476void477AcpiDmClearExternalFileList (478void)479{480ACPI_EXTERNAL_FILE *NextExternal;481482483while (AcpiGbl_ExternalFileList)484{485NextExternal = AcpiGbl_ExternalFileList->Next;486ACPI_FREE (AcpiGbl_ExternalFileList->Path);487ACPI_FREE (AcpiGbl_ExternalFileList);488AcpiGbl_ExternalFileList = NextExternal;489}490}491492493/*******************************************************************************494*495* FUNCTION: AcpiDmGetExternalsFromFile496*497* PARAMETERS: None498*499* RETURN: None500*501* DESCRIPTION: Process the optional external reference file.502*503* Each line in the file should be of the form:504* External (<Method namepath>, MethodObj, <ArgCount>)505*506* Example:507* External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)508*509******************************************************************************/510511void512AcpiDmGetExternalsFromFile (513void)514{515FILE *ExternalRefFile;516char *Token;517char *MethodName;518UINT32 ArgCount;519UINT32 ImportCount = 0;520521522if (!AslGbl_ExternalRefFilename)523{524return;525}526527/* Open the file */528529ExternalRefFile = fopen (AslGbl_ExternalRefFilename, "r");530if (!ExternalRefFile)531{532fprintf (stderr, "Could not open external reference file \"%s\"\n",533AslGbl_ExternalRefFilename);534AslAbort ();535return;536}537538/* Each line defines a method */539540while (fgets (AslGbl_StringBuffer, ASL_STRING_BUFFER_SIZE, ExternalRefFile))541{542Token = strtok (AslGbl_StringBuffer, METHOD_SEPARATORS); /* "External" */543if (!Token)544{545continue;546}547548if (strcmp (Token, "External"))549{550continue;551}552553MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */554if (!MethodName)555{556continue;557}558559Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */560if (!Token)561{562continue;563}564565if (strcmp (Token, "MethodObj"))566{567continue;568}569570Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */571if (!Token)572{573continue;574}575576/* Convert arg count string to an integer */577578errno = 0;579ArgCount = strtoul (Token, NULL, 0);580if (errno)581{582fprintf (stderr, "Invalid argument count (%s)\n", Token);583continue;584}585586if (ArgCount > 7)587{588fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);589continue;590}591592/* Add this external to the global list */593594AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",595AslGbl_ExternalRefFilename, ArgCount, MethodName);596597AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,598ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));599ImportCount++;600}601602if (!ImportCount)603{604fprintf (stderr,605"Did not find any external methods in reference file \"%s\"\n",606AslGbl_ExternalRefFilename);607}608else609{610/* Add the external(s) to the namespace */611612AcpiDmAddExternalListToNamespace ();613614AcpiOsPrintf ("%s: Imported %u external method definitions\n",615AslGbl_ExternalRefFilename, ImportCount);616}617618fclose (ExternalRefFile);619}620621622/*******************************************************************************623*624* FUNCTION: AcpiDmAddOpToExternalList625*626* PARAMETERS: Op - Current parser Op627* Path - Internal (AML) path to the object628* Type - ACPI object type to be added629* Value - Arg count if adding a Method object630* Flags - To be passed to the external object631*632* RETURN: None633*634* DESCRIPTION: Insert a new name into the global list of Externals which635* will in turn be later emitted as an External() declaration636* in the disassembled output.637*638* This function handles the most common case where the referenced639* name is simply not found in the constructed namespace.640*641******************************************************************************/642643void644AcpiDmAddOpToExternalList (645ACPI_PARSE_OBJECT *Op,646char *Path,647UINT8 Type,648UINT32 Value,649UINT16 Flags)650{651char *ExternalPath;652char *InternalPath = Path;653char *Temp;654ACPI_STATUS Status;655656657ACPI_FUNCTION_TRACE (DmAddOpToExternalList);658659660if (!Path)661{662return_VOID;663}664665/* Remove a root backslash if present */666667if ((*Path == AML_ROOT_PREFIX) && (Path[1]))668{669Path++;670}671672/* Externalize the pathname */673674Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,675NULL, &ExternalPath);676if (ACPI_FAILURE (Status))677{678return_VOID;679}680681/*682* Get the full pathname from the root if "Path" has one or more683* parent prefixes (^). Note: path will not contain a leading '\'.684*/685if (*Path == (UINT8) AML_PARENT_PREFIX)686{687Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);688689/* Set new external path */690691ACPI_FREE (ExternalPath);692ExternalPath = Temp;693if (!Temp)694{695return_VOID;696}697698/* Create the new internal pathname */699700Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;701Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);702if (ACPI_FAILURE (Status))703{704ACPI_FREE (ExternalPath);705return_VOID;706}707}708709/* Create the new External() declaration node */710711Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,712Type, Value, Flags);713if (ACPI_FAILURE (Status))714{715ACPI_FREE (ExternalPath);716if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)717{718ACPI_FREE (InternalPath);719}720}721722return_VOID;723}724725726/*******************************************************************************727*728* FUNCTION: AcpiDmGetExternalAndInternalPath729*730* PARAMETERS: Node - Namespace node for object to be added731* ExternalPath - Will contain the external path of the node732* InternalPath - Will contain the internal path of the node733*734* RETURN: None735*736* DESCRIPTION: Get the External and Internal path from the given node.737*738******************************************************************************/739740static ACPI_STATUS741AcpiDmGetExternalAndInternalPath (742ACPI_NAMESPACE_NODE *Node,743char **ExternalPath,744char **InternalPath)745{746ACPI_STATUS Status;747748749if (!Node)750{751return (AE_BAD_PARAMETER);752}753754/* Get the full external and internal pathnames to the node */755756*ExternalPath = AcpiNsGetExternalPathname (Node);757if (!*ExternalPath)758{759return (AE_BAD_PATHNAME);760}761762Status = AcpiNsInternalizeName (*ExternalPath, InternalPath);763if (ACPI_FAILURE (Status))764{765ACPI_FREE (*ExternalPath);766return (Status);767}768769return (AE_OK);770}771772773/*******************************************************************************774*775* FUNCTION: AcpiDmRemoveRootPrefix776*777* PARAMETERS: Path - Remove Root prefix from this Path778*779* RETURN: None780*781* DESCRIPTION: Remove the root prefix character '\' from Path.782*783******************************************************************************/784785static ACPI_STATUS786AcpiDmRemoveRootPrefix (787char **Path)788{789char *InputPath = *Path;790791792if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1]))793{794if (!memmove(InputPath, InputPath+1, strlen(InputPath)))795{796return (AE_ERROR);797}798799*Path = InputPath;800}801802return (AE_OK);803}804805806/*******************************************************************************807*808* FUNCTION: AcpiDmAddNodeToExternalList809*810* PARAMETERS: Node - Namespace node for object to be added811* Type - ACPI object type to be added812* Value - Arg count if adding a Method object813* Flags - To be passed to the external object814*815* RETURN: None816*817* DESCRIPTION: Insert a new name into the global list of Externals which818* will in turn be later emitted as an External() declaration819* in the disassembled output.820*821* This function handles the case where the referenced name has822* been found in the namespace, but the name originated in a823* table other than the one that is being disassembled (such824* as a table that is added via the iASL -e option).825*826******************************************************************************/827828void829AcpiDmAddNodeToExternalList (830ACPI_NAMESPACE_NODE *Node,831UINT8 Type,832UINT32 Value,833UINT16 Flags)834{835char *ExternalPath;836char *InternalPath;837ACPI_STATUS Status;838839840ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);841842/* Get the full external and internal pathnames to the node */843844Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath);845if (ACPI_FAILURE (Status))846{847return_VOID;848}849850/* Remove the root backslash */851852Status = AcpiDmRemoveRootPrefix (&ExternalPath);853if (ACPI_FAILURE (Status))854{855ACPI_FREE (ExternalPath);856ACPI_FREE (InternalPath);857return_VOID;858}859860/* Create the new External() declaration node */861862Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,863Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));864if (ACPI_FAILURE (Status))865{866ACPI_FREE (ExternalPath);867ACPI_FREE (InternalPath);868}869870return_VOID;871}872873874/*******************************************************************************875*876* FUNCTION: AcpiDmAddPathToExternalList877*878* PARAMETERS: Path - External name of the object to be added879* Type - ACPI object type to be added880* Value - Arg count if adding a Method object881* Flags - To be passed to the external object882*883* RETURN: None884*885* DESCRIPTION: Insert a new name into the global list of Externals which886* will in turn be later emitted as an External() declaration887* in the disassembled output.888*889* This function currently is used to add externals via a890* reference file (via the -fe iASL option).891*892******************************************************************************/893894static void895AcpiDmAddPathToExternalList (896char *Path,897UINT8 Type,898UINT32 Value,899UINT16 Flags)900{901char *InternalPath;902char *ExternalPath;903ACPI_STATUS Status;904905906ACPI_FUNCTION_TRACE (DmAddPathToExternalList);907908909if (!Path)910{911return_VOID;912}913914/* Remove a root backslash if present */915916if ((*Path == AML_ROOT_PREFIX) && (Path[1]))917{918Path++;919}920921/* Create the internal and external pathnames */922923Status = AcpiNsInternalizeName (Path, &InternalPath);924if (ACPI_FAILURE (Status))925{926return_VOID;927}928929Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,930NULL, &ExternalPath);931if (ACPI_FAILURE (Status))932{933ACPI_FREE (InternalPath);934return_VOID;935}936937/* Create the new External() declaration node */938939Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,940Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));941if (ACPI_FAILURE (Status))942{943ACPI_FREE (ExternalPath);944ACPI_FREE (InternalPath);945}946947return_VOID;948}949950951/*******************************************************************************952*953* FUNCTION: AcpiDmCreateNewExternal954*955* PARAMETERS: ExternalPath - External path to the object956* InternalPath - Internal (AML) path to the object957* Type - ACPI object type to be added958* Value - Arg count if adding a Method object959* Flags - To be passed to the external object960*961* RETURN: Status962*963* DESCRIPTION: Common low-level function to insert a new name into the global964* list of Externals which will in turn be later emitted as965* External() declarations in the disassembled output.966*967* Note: The external name should not include a root prefix968* (backslash). We do not want External() statements to contain969* a leading '\', as this prevents duplicate external statements970* of the form:971*972* External (\ABCD)973* External (ABCD)974*975* This would cause a compile time error when the disassembled976* output file is recompiled.977*978* There are two cases that are handled here. For both, we emit979* an External() statement:980* 1) The name was simply not found in the namespace.981* 2) The name was found, but it originated in a table other than982* the table that is being disassembled.983*984******************************************************************************/985986static ACPI_STATUS987AcpiDmCreateNewExternal (988char *ExternalPath,989char *InternalPath,990UINT8 Type,991UINT32 Value,992UINT16 Flags)993{994ACPI_EXTERNAL_LIST *NewExternal;995ACPI_EXTERNAL_LIST *NextExternal;996ACPI_EXTERNAL_LIST *PrevExternal = NULL;997998999ACPI_FUNCTION_TRACE (DmCreateNewExternal);100010011002/* Check all existing externals to ensure no duplicates */10031004NextExternal = AcpiGbl_ExternalList;1005while (NextExternal)1006{1007/* Check for duplicates */10081009if (!strcmp (ExternalPath, NextExternal->Path))1010{1011/*1012* If this external came from an External() opcode, we are1013* finished with this one. (No need to check any further).1014*/1015if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)1016{1017return_ACPI_STATUS (AE_ALREADY_EXISTS);1018}10191020/* Allow upgrade of type from ANY */10211022else if ((NextExternal->Type == ACPI_TYPE_ANY) &&1023(Type != ACPI_TYPE_ANY))1024{1025NextExternal->Type = Type;1026}10271028/* Update the argument count as necessary */10291030if (Value < NextExternal->Value)1031{1032NextExternal->Value = Value;1033}10341035/* Update flags. */10361037NextExternal->Flags |= Flags;1038NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;10391040return_ACPI_STATUS (AE_ALREADY_EXISTS);1041}10421043NextExternal = NextExternal->Next;1044}10451046/* Allocate and init a new External() descriptor */10471048NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));1049if (!NewExternal)1050{1051return_ACPI_STATUS (AE_NO_MEMORY);1052}10531054ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,1055"Adding external reference node (%s) type [%s]\n",1056ExternalPath, AcpiUtGetTypeName (Type)));10571058NewExternal->Flags = Flags;1059NewExternal->Value = Value;1060NewExternal->Path = ExternalPath;1061NewExternal->Type = Type;1062NewExternal->Length = (UINT16) strlen (ExternalPath);1063NewExternal->InternalPath = InternalPath;10641065/* Link the new descriptor into the global list, alphabetically ordered */10661067NextExternal = AcpiGbl_ExternalList;1068while (NextExternal)1069{1070if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)1071{1072if (PrevExternal)1073{1074PrevExternal->Next = NewExternal;1075}1076else1077{1078AcpiGbl_ExternalList = NewExternal;1079}10801081NewExternal->Next = NextExternal;1082return_ACPI_STATUS (AE_OK);1083}10841085PrevExternal = NextExternal;1086NextExternal = NextExternal->Next;1087}10881089if (PrevExternal)1090{1091PrevExternal->Next = NewExternal;1092}1093else1094{1095AcpiGbl_ExternalList = NewExternal;1096}10971098return_ACPI_STATUS (AE_OK);1099}110011011102/*******************************************************************************1103*1104* FUNCTION: AcpiDmResolveExternal1105*1106* PARAMETERS: Path - Path of the external1107* Type - Type of the external1108* Node - Input node for AcpiNsLookup1109*1110* RETURN: Status1111*1112* DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup.1113* If the returned node is an external and has the same type1114* we assume that it was either an existing external or a1115*1116******************************************************************************/11171118static ACPI_STATUS1119AcpiDmResolveExternal (1120char *Path,1121UINT8 Type,1122ACPI_NAMESPACE_NODE **Node)1123{1124ACPI_STATUS Status;112511261127Status = AcpiNsLookup (NULL, Path, Type,1128ACPI_IMODE_LOAD_PASS1,1129ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,1130NULL, Node);11311132if (!Node)1133{1134ACPI_EXCEPTION ((AE_INFO, Status,1135"while adding external to namespace [%s]", Path));1136}11371138/* Note the asl code "external(a) external(a)" is acceptable ASL */11391140else if ((*Node)->Type == Type &&1141(*Node)->Flags & ANOBJ_IS_EXTERNAL)1142{1143return (AE_OK);1144}1145else1146{1147ACPI_EXCEPTION ((AE_INFO, AE_ERROR,1148"[%s] has conflicting declarations", Path));1149}11501151return (AE_ERROR);1152}115311541155/*******************************************************************************1156*1157* FUNCTION: AcpiDmCreateSubobjectForExternal1158*1159* PARAMETERS: Type - Type of the external1160* Node - Namespace node from AcpiNsLookup1161* ParamCount - Value to be used for Method1162*1163* RETURN: None1164*1165* DESCRIPTION: Add one external to the namespace. Allows external to be1166* "resolved".1167*1168******************************************************************************/11691170void1171AcpiDmCreateSubobjectForExternal (1172UINT8 Type,1173ACPI_NAMESPACE_NODE **Node,1174UINT32 ParamCount)1175{1176ACPI_OPERAND_OBJECT *ObjDesc;117711781179switch (Type)1180{1181case ACPI_TYPE_METHOD:11821183/* For methods, we need to save the argument count */11841185ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);1186ObjDesc->Method.ParamCount = (UINT8) ParamCount;1187(*Node)->Object = ObjDesc;1188break;11891190case ACPI_TYPE_REGION:11911192/* Regions require a region sub-object */11931194ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);1195ObjDesc->Region.Node = *Node;1196(*Node)->Object = ObjDesc;1197break;11981199default:12001201break;1202}1203}120412051206/*******************************************************************************1207*1208* FUNCTION: AcpiDmAddOneExternalToNamespace1209*1210* PARAMETERS: Path - External parse object1211* Type - Type of parse object1212* ParamCount - External method parameter count1213*1214* RETURN: None1215*1216* DESCRIPTION: Add one external to the namespace by resolvign the external1217* (by performing a namespace lookup) and annotating the resulting1218* namespace node with the appropriate information if the type1219* is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.1220*1221******************************************************************************/12221223void1224AcpiDmAddOneExternalToNamespace (1225char *Path,1226UINT8 Type,1227UINT32 ParamCount)1228{1229ACPI_STATUS Status;1230ACPI_NAMESPACE_NODE *Node;123112321233Status = AcpiDmResolveExternal (Path, Type, &Node);12341235if (ACPI_FAILURE (Status))1236{1237return;1238}12391240AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount);12411242}124312441245/*******************************************************************************1246*1247* FUNCTION: AcpiDmAddExternalListToNamespace1248*1249* PARAMETERS: None1250*1251* RETURN: None1252*1253* DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace.1254* Allows externals to be "resolved".1255*1256******************************************************************************/12571258void1259AcpiDmAddExternalListToNamespace (1260void)1261{1262ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;126312641265while (External)1266{1267AcpiDmAddOneExternalToNamespace (External->InternalPath,1268External->Type, External->Value);1269External = External->Next;1270}1271}127212731274/*******************************************************************************1275*1276* FUNCTION: AcpiDmGetUnresolvedExternalMethodCount1277*1278* PARAMETERS: None1279*1280* RETURN: The number of unresolved control method externals in the1281* external list1282*1283* DESCRIPTION: Return the number of unresolved external methods that have been1284* generated. If any unresolved control method externals have been1285* found, we must re-parse the entire definition block with the new1286* information (number of arguments for the methods.)1287* This is limitation of AML, we don't know the number of arguments1288* from the control method invocation itself.1289*1290* Note: resolved external control methods are external control1291* methods encoded with the AML_EXTERNAL_OP bytecode within the1292* AML being disassembled.1293*1294******************************************************************************/12951296UINT321297AcpiDmGetUnresolvedExternalMethodCount (1298void)1299{1300ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;1301UINT32 Count = 0;130213031304while (External)1305{1306if (External->Type == ACPI_TYPE_METHOD &&1307!(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE))1308{1309Count++;1310}13111312External = External->Next;1313}13141315return (Count);1316}131713181319/*******************************************************************************1320*1321* FUNCTION: AcpiDmClearExternalList1322*1323* PARAMETERS: None1324*1325* RETURN: None1326*1327* DESCRIPTION: Free the entire External info list1328*1329******************************************************************************/13301331void1332AcpiDmClearExternalList (1333void)1334{1335ACPI_EXTERNAL_LIST *NextExternal;133613371338while (AcpiGbl_ExternalList)1339{1340NextExternal = AcpiGbl_ExternalList->Next;1341ACPI_FREE (AcpiGbl_ExternalList->Path);1342ACPI_FREE (AcpiGbl_ExternalList);1343AcpiGbl_ExternalList = NextExternal;1344}1345}134613471348/*******************************************************************************1349*1350* FUNCTION: AcpiDmEmitExternals1351*1352* PARAMETERS: None1353*1354* RETURN: None1355*1356* DESCRIPTION: Emit an External() ASL statement for each of the externals in1357* the global external info list.1358*1359******************************************************************************/13601361void1362AcpiDmEmitExternals (1363void)1364{1365ACPI_EXTERNAL_LIST *NextExternal;136613671368if (!AcpiGbl_ExternalList)1369{1370return;1371}13721373/*1374* Determine the number of control methods in the external list, and1375* also how many of those externals were resolved via the namespace.1376*/1377NextExternal = AcpiGbl_ExternalList;1378while (NextExternal)1379{1380if (NextExternal->Type == ACPI_TYPE_METHOD)1381{1382AcpiGbl_NumExternalMethods++;1383if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)1384{1385AcpiGbl_ResolvedExternalMethods++;1386}1387}13881389NextExternal = NextExternal->Next;1390}13911392/* Check if any control methods were unresolved */13931394AcpiDmUnresolvedWarning (1);13951396if (AslGbl_ExternalRefFilename)1397{1398AcpiOsPrintf (1399" /*\n * External declarations were imported from\n"1400" * a reference file -- %s\n */\n\n",1401AslGbl_ExternalRefFilename);1402}14031404/*1405* Walk and emit the list of externals found during the AML parsing1406*/1407while (AcpiGbl_ExternalList)1408{1409if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))1410{1411AcpiOsPrintf (" External (%s%s)",1412AcpiGbl_ExternalList->Path,1413AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));14141415/* Check for "unresolved" method reference */14161417if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&1418(!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))1419{1420AcpiOsPrintf (" // Warning: Unknown method, "1421"guessing %u arguments",1422AcpiGbl_ExternalList->Value);1423}14241425/* Check for external from a external references file */14261427else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)1428{1429if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)1430{1431AcpiOsPrintf (" // %u Arguments",1432AcpiGbl_ExternalList->Value);1433}14341435AcpiOsPrintf (" // From external reference file");1436}14371438/* This is the normal external case */14391440else1441{1442/* For methods, add a comment with the number of arguments */14431444if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)1445{1446AcpiOsPrintf (" // %u Arguments",1447AcpiGbl_ExternalList->Value);1448}1449}14501451if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION)1452{1453AcpiOsPrintf ("%s", ExternalConflictMessage);1454AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path);1455}1456AcpiOsPrintf ("\n");1457}14581459/* Free this external info block and move on to next external */14601461NextExternal = AcpiGbl_ExternalList->Next;1462if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)1463{1464ACPI_FREE (AcpiGbl_ExternalList->InternalPath);1465}14661467ACPI_FREE (AcpiGbl_ExternalList->Path);1468ACPI_FREE (AcpiGbl_ExternalList);1469AcpiGbl_ExternalList = NextExternal;1470}14711472AcpiOsPrintf ("\n");1473}147414751476/*******************************************************************************1477*1478* FUNCTION: AcpiDmMarkExternalConflict1479*1480* PARAMETERS: Path - Namepath to search1481*1482* RETURN: ExternalList1483*1484* DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path1485*1486******************************************************************************/14871488void1489AcpiDmMarkExternalConflict (1490ACPI_NAMESPACE_NODE *Node)1491{1492ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;1493char *ExternalPath;1494char *InternalPath;1495ACPI_STATUS Status;149614971498ACPI_FUNCTION_TRACE (DmMarkExternalConflict);149915001501if (Node->Flags & ANOBJ_IS_EXTERNAL)1502{1503return_VOID;1504}15051506/* Get the full external and internal pathnames to the node */15071508Status = AcpiDmGetExternalAndInternalPath (Node,1509&ExternalPath, &InternalPath);1510if (ACPI_FAILURE (Status))1511{1512return_VOID;1513}15141515/* Remove the root backslash */15161517Status = AcpiDmRemoveRootPrefix (&InternalPath);1518if (ACPI_FAILURE (Status))1519{1520ACPI_FREE (InternalPath);1521ACPI_FREE (ExternalPath);1522return_VOID;1523}15241525while (ExternalList)1526{1527if (!strcmp (ExternalList->InternalPath, InternalPath))1528{1529ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION;1530}1531ExternalList = ExternalList->Next;1532}15331534ACPI_FREE (InternalPath);1535ACPI_FREE (ExternalPath);15361537return_VOID;1538}153915401541/*******************************************************************************1542*1543* FUNCTION: AcpiDmConflictingDeclaration1544*1545* PARAMETERS: Path - Path with conflicting declaration1546*1547* RETURN: None1548*1549* DESCRIPTION: Emit a warning when printing conflicting ASL external1550* declarations.1551*1552******************************************************************************/15531554static void1555AcpiDmConflictingDeclaration (1556char *Path)1557{1558fprintf (stderr,1559" Warning - Emitting ASL code \"External (%s)\"\n"1560" This is a conflicting declaration with some "1561"other declaration within the ASL code.\n"1562" This external declaration may need to be "1563"deleted in order to recompile the dsl file.\n\n",1564Path);1565}156615671568/*******************************************************************************1569*1570* FUNCTION: AcpiDmEmitExternal1571*1572* PARAMETERS: Op External Parse Object1573*1574* RETURN: None1575*1576* DESCRIPTION: Emit an External() ASL statement for the current External1577* parse object. Note: External Ops are named types so the1578* namepath is contained within NameOp->Name.Path.1579*1580******************************************************************************/15811582void1583AcpiDmEmitExternal (1584ACPI_PARSE_OBJECT *NameOp,1585ACPI_PARSE_OBJECT *TypeOp)1586{1587AcpiOsPrintf ("External (");1588AcpiDmNamestring (NameOp->Named.Path);1589AcpiOsPrintf ("%s)",1590AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));1591AcpiDmCheckForExternalConflict (NameOp->Named.Path);1592AcpiOsPrintf ("\n");1593}159415951596/*******************************************************************************1597*1598* FUNCTION: AcpiDmCheckForExternalConflict1599*1600* PARAMETERS: Path - Path to check1601*1602* RETURN: None1603*1604* DESCRIPTION: Search the External List to see if the input Path has a1605* conflicting declaration.1606*1607******************************************************************************/16081609static void1610AcpiDmCheckForExternalConflict (1611char *Path)1612{1613ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;1614char *ListItemPath;1615char *InputPath;161616171618if (!Path)1619{1620return;1621}16221623/* Move past the root prefix '\' */16241625InputPath = Path;1626if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1])1627{1628InputPath++;1629}16301631while (ExternalList)1632{1633ListItemPath = ExternalList->Path;1634if (ListItemPath)1635{1636/* Move past the root prefix '\' */16371638if ((*ListItemPath == AML_ROOT_PREFIX) &&1639ListItemPath[1])1640{1641ListItemPath++;1642}16431644if (!strcmp (ListItemPath, InputPath) &&1645(ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION))1646{1647AcpiOsPrintf ("%s", ExternalConflictMessage);1648AcpiDmConflictingDeclaration (Path);16491650return;1651}1652}1653ExternalList = ExternalList->Next;1654}1655}1656/*******************************************************************************1657*1658* FUNCTION: AcpiDmUnresolvedWarning1659*1660* PARAMETERS: Type - Where to output the warning.1661* 0 means write to stderr1662* 1 means write to AcpiOsPrintf1663*1664* RETURN: None1665*1666* DESCRIPTION: Issue warning message if there are unresolved external control1667* methods within the disassembly.1668*1669******************************************************************************/16701671/*1672Summary of the external control method problem:16731674When the -e option is used with disassembly, the various SSDTs are simply1675loaded into a global namespace for the disassembler to use in order to1676resolve control method references (invocations).16771678The disassembler tracks any such references, and will emit an External()1679statement for these types of methods, with the proper number of arguments .16801681Without the SSDTs, the AML does not contain enough information to properly1682disassemble the control method invocation -- because the disassembler does1683not know how many arguments to parse.16841685An example: Assume we have two control methods. ABCD has one argument, and1686EFGH has zero arguments. Further, we have two additional control methods1687that invoke ABCD and EFGH, named T1 and T2:16881689Method (ABCD, 1)1690{1691}1692Method (EFGH, 0)1693{1694}1695Method (T1)1696{1697ABCD (Add (2, 7, Local0))1698}1699Method (T2)1700{1701EFGH ()1702Add (2, 7, Local0)1703}17041705Here is the AML code that is generated for T1 and T2:17061707185: Method (T1)170817090000034C: 14 10 54 31 5F 5F 00 ... "..T1__."17101711186: {1712187: ABCD (Add (2, 7, Local0))1713171400000353: 41 42 43 44 ............ "ABCD"171500000357: 72 0A 02 0A 07 60 ...... "r....`"17161717188: }17181719190: Method (T2)172017210000035D: 14 10 54 32 5F 5F 00 ... "..T2__."17221723191: {1724192: EFGH ()1725172600000364: 45 46 47 48 ............ "EFGH"17271728193: Add (2, 7, Local0)1729173000000368: 72 0A 02 0A 07 60 ...... "r....`"1731194: }17321733Note that the AML code for T1 and T2 is essentially identical. When1734disassembling this code, the methods ABCD and EFGH must be known to the1735disassembler, otherwise it does not know how to handle the method invocations.17361737In other words, if ABCD and EFGH are actually external control methods1738appearing in an SSDT, the disassembler does not know what to do unless1739the owning SSDT has been loaded via the -e option.1740*/17411742static char ExternalWarningPart1[600];1743static char ExternalWarningPart2[400];1744static char ExternalWarningPart3[400];1745static char ExternalWarningPart4[200];17461747void1748AcpiDmUnresolvedWarning (1749UINT8 Type)1750{1751char *Format;1752char Pad[] = " *";1753char NoPad[] = "";175417551756if (!AcpiGbl_NumExternalMethods)1757{1758return;1759}17601761if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)1762{1763return;1764}17651766Format = Type ? Pad : NoPad;17671768sprintf (ExternalWarningPart1,1769"%s iASL Warning: There %s %u external control method%s found during\n"1770"%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"1771"%s ACPI tables may be required to properly disassemble the code. This\n"1772"%s resulting disassembler output file may not compile because the\n"1773"%s disassembler did not know how many arguments to assign to the\n"1774"%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"1775"%s runtime and may or may not be available via the host OS.\n",1776Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),1777AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),1778Format, AcpiGbl_ResolvedExternalMethods,1779(AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),1780(AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),1781Format, Format, Format, Format, Format);17821783sprintf (ExternalWarningPart2,1784"%s To specify the tables needed to resolve external control method\n"1785"%s references, the -e option can be used to specify the filenames.\n"1786"%s Example iASL invocations:\n"1787"%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"1788"%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"1789"%s iasl -e ssdt*.aml -d dsdt.aml\n",1790Format, Format, Format, Format, Format, Format);17911792sprintf (ExternalWarningPart3,1793"%s In addition, the -fe option can be used to specify a file containing\n"1794"%s control method external declarations with the associated method\n"1795"%s argument counts. Each line of the file must be of the form:\n"1796"%s External (<method pathname>, MethodObj, <argument count>)\n"1797"%s Invocation:\n"1798"%s iasl -fe refs.txt -d dsdt.aml\n",1799Format, Format, Format, Format, Format, Format);18001801sprintf (ExternalWarningPart4,1802"%s The following methods were unresolved and many not compile properly\n"1803"%s because the disassembler had to guess at the number of arguments\n"1804"%s required for each:\n",1805Format, Format, Format);18061807if (Type)1808{1809if (!AcpiGbl_ExternalFileList)1810{1811/* The -e option was not specified */18121813AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n",1814ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,1815ExternalWarningPart4);1816}1817else1818{1819/* The -e option was specified, but there are still some unresolved externals */18201821AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n",1822ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);1823}1824}1825else1826{1827if (!AcpiGbl_ExternalFileList)1828{1829/* The -e option was not specified */18301831fprintf (stderr, "\n%s\n%s\n%s\n",1832ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);1833}1834else1835{1836/* The -e option was specified, but there are still some unresolved externals */18371838fprintf (stderr, "\n%s\n%s\n",1839ExternalWarningPart1, ExternalWarningPart3);1840}1841}1842}184318441845