12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424 |
- /******************************************************************************
- *
- * Module Name: dmextern - Support for External() ASL statements
- *
- *****************************************************************************/
- /******************************************************************************
- *
- * 1. Copyright Notice
- *
- * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp.
- * All rights reserved.
- *
- * 2. License
- *
- * 2.1. This is your license from Intel Corp. under its intellectual property
- * rights. You may have additional license terms from the party that provided
- * you this software, covering your right to use that party's intellectual
- * property rights.
- *
- * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
- * copy of the source code appearing in this file ("Covered Code") an
- * irrevocable, perpetual, worldwide license under Intel's copyrights in the
- * base code distributed originally by Intel ("Original Intel Code") to copy,
- * make derivatives, distribute, use and display any portion of the Covered
- * Code in any form, with the right to sublicense such rights; and
- *
- * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
- * license (with the right to sublicense), under only those claims of Intel
- * patents that are infringed by the Original Intel Code, to make, use, sell,
- * offer to sell, and import the Covered Code and derivative works thereof
- * solely to the minimum extent necessary to exercise the above copyright
- * license, and in no event shall the patent license extend to any additions
- * to or modifications of the Original Intel Code. No other license or right
- * is granted directly or by implication, estoppel or otherwise;
- *
- * The above copyright and patent license is granted only if the following
- * conditions are met:
- *
- * 3. Conditions
- *
- * 3.1. Redistribution of Source with Rights to Further Distribute Source.
- * Redistribution of source code of any substantial portion of the Covered
- * Code or modification with rights to further distribute source must include
- * the above Copyright Notice, the above License, this list of Conditions,
- * and the following Disclaimer and Export Compliance provision. In addition,
- * Licensee must cause all Covered Code to which Licensee contributes to
- * contain a file documenting the changes Licensee made to create that Covered
- * Code and the date of any change. Licensee must include in that file the
- * documentation of any changes made by any predecessor Licensee. Licensee
- * must include a prominent statement that the modification is derived,
- * directly or indirectly, from Original Intel Code.
- *
- * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
- * Redistribution of source code of any substantial portion of the Covered
- * Code or modification without rights to further distribute source must
- * include the following Disclaimer and Export Compliance provision in the
- * documentation and/or other materials provided with distribution. In
- * addition, Licensee may not authorize further sublicense of source of any
- * portion of the Covered Code, and must include terms to the effect that the
- * license from Licensee to its licensee is limited to the intellectual
- * property embodied in the software Licensee provides to its licensee, and
- * not to intellectual property embodied in modifications its licensee may
- * make.
- *
- * 3.3. Redistribution of Executable. Redistribution in executable form of any
- * substantial portion of the Covered Code or modification must reproduce the
- * above Copyright Notice, and the following Disclaimer and Export Compliance
- * provision in the documentation and/or other materials provided with the
- * distribution.
- *
- * 3.4. Intel retains all right, title, and interest in and to the Original
- * Intel Code.
- *
- * 3.5. Neither the name Intel nor any other trademark owned or controlled by
- * Intel shall be used in advertising or otherwise to promote the sale, use or
- * other dealings in products derived from or relating to the Covered Code
- * without prior written authorization from Intel.
- *
- * 4. Disclaimer and Export Compliance
- *
- * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
- * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
- * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
- * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
- * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
- * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
- * PARTICULAR PURPOSE.
- *
- * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
- * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
- * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
- * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
- * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
- * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
- * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
- * LIMITED REMEDY.
- *
- * 4.3. Licensee shall not export, either directly or indirectly, any of this
- * software or system incorporating such software without first obtaining any
- * required license or other approval from the U. S. Department of Commerce or
- * any other agency or department of the United States Government. In the
- * event Licensee exports any such software from the United States or
- * re-exports any such software from a foreign destination, Licensee shall
- * ensure that the distribution and export/re-export of the software is in
- * compliance with all laws, regulations, orders, or other restrictions of the
- * U.S. Export Administration Regulations. Licensee agrees that neither it nor
- * any of its subsidiaries will export/re-export any technical data, process,
- * software, or service, directly or indirectly, to any country for which the
- * United States government or any agency thereof requires an export license,
- * other governmental approval, or letter of assurance, without first obtaining
- * such license, approval or letter.
- *
- *****************************************************************************/
- #include "acpi.h"
- #include "accommon.h"
- #include "amlcode.h"
- #include "acnamesp.h"
- #include "acdisasm.h"
- #include "aslcompiler.h"
- #include <stdio.h>
- #include <errno.h>
- /*
- * This module is used for application-level code (iASL disassembler) only.
- *
- * It contains the code to create and emit any necessary External() ASL
- * statements for the module being disassembled.
- */
- #define _COMPONENT ACPI_CA_DISASSEMBLER
- ACPI_MODULE_NAME ("dmextern")
- /*
- * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
- * ObjectTypeKeyword. Used to generate typed external declarations
- */
- static const char *AcpiGbl_DmTypeNames[] =
- {
- /* 00 */ ", UnknownObj", /* Type ANY */
- /* 01 */ ", IntObj",
- /* 02 */ ", StrObj",
- /* 03 */ ", BuffObj",
- /* 04 */ ", PkgObj",
- /* 05 */ ", FieldUnitObj",
- /* 06 */ ", DeviceObj",
- /* 07 */ ", EventObj",
- /* 08 */ ", MethodObj",
- /* 09 */ ", MutexObj",
- /* 10 */ ", OpRegionObj",
- /* 11 */ ", PowerResObj",
- /* 12 */ ", ProcessorObj",
- /* 13 */ ", ThermalZoneObj",
- /* 14 */ ", BuffFieldObj",
- /* 15 */ ", DDBHandleObj",
- /* 16 */ "", /* Debug object */
- /* 17 */ ", FieldUnitObj",
- /* 18 */ ", FieldUnitObj",
- /* 19 */ ", FieldUnitObj"
- };
- #define METHOD_SEPARATORS " \t,()\n"
- /* Local prototypes */
- static const char *
- AcpiDmGetObjectTypeName (
- ACPI_OBJECT_TYPE Type);
- static char *
- AcpiDmNormalizeParentPrefix (
- ACPI_PARSE_OBJECT *Op,
- char *Path);
- static void
- AcpiDmAddPathToExternalList (
- char *Path,
- UINT8 Type,
- UINT32 Value,
- UINT16 Flags);
- static ACPI_STATUS
- AcpiDmCreateNewExternal (
- char *ExternalPath,
- char *InternalPath,
- UINT8 Type,
- UINT32 Value,
- UINT16 Flags);
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmGetObjectTypeName
- *
- * PARAMETERS: Type - An ACPI_OBJECT_TYPE
- *
- * RETURN: Pointer to a string
- *
- * DESCRIPTION: Map an object type to the ASL object type string.
- *
- ******************************************************************************/
- static const char *
- AcpiDmGetObjectTypeName (
- ACPI_OBJECT_TYPE Type)
- {
- if (Type == ACPI_TYPE_LOCAL_SCOPE)
- {
- Type = ACPI_TYPE_DEVICE;
- }
- else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
- {
- return ("");
- }
- return (AcpiGbl_DmTypeNames[Type]);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmNormalizeParentPrefix
- *
- * PARAMETERS: Op - Parse op
- * Path - Path with parent prefix
- *
- * RETURN: The full pathname to the object (from the namespace root)
- *
- * DESCRIPTION: Returns the full pathname of a path with parent prefix
- * The caller must free the fullpath returned.
- *
- ******************************************************************************/
- static char *
- AcpiDmNormalizeParentPrefix (
- ACPI_PARSE_OBJECT *Op,
- char *Path)
- {
- ACPI_NAMESPACE_NODE *Node;
- char *Fullpath;
- char *ParentPath;
- ACPI_SIZE Length;
- UINT32 Index = 0;
- if (!Op)
- {
- return (NULL);
- }
- /* Search upwards in the parse tree until we reach the next namespace node */
- Op = Op->Common.Parent;
- while (Op)
- {
- if (Op->Common.Node)
- {
- break;
- }
- Op = Op->Common.Parent;
- }
- if (!Op)
- {
- return (NULL);
- }
- /*
- * Find the actual parent node for the reference:
- * Remove all carat prefixes from the input path.
- * There may be multiple parent prefixes (For example, ^^^M000)
- */
- Node = Op->Common.Node;
- while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
- {
- Node = Node->Parent;
- Path++;
- }
- if (!Node)
- {
- return (NULL);
- }
- /* Get the full pathname for the parent node */
- ParentPath = AcpiNsGetExternalPathname (Node);
- if (!ParentPath)
- {
- return (NULL);
- }
- Length = (strlen (ParentPath) + strlen (Path) + 1);
- if (ParentPath[1])
- {
- /*
- * If ParentPath is not just a simple '\', increment the length
- * for the required dot separator (ParentPath.Path)
- */
- Length++;
- /* For External() statements, we do not want a leading '\' */
- if (*ParentPath == AML_ROOT_PREFIX)
- {
- Index = 1;
- }
- }
- Fullpath = ACPI_ALLOCATE_ZEROED (Length);
- if (!Fullpath)
- {
- goto Cleanup;
- }
- /*
- * Concatenate parent fullpath and path. For example,
- * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
- *
- * Copy the parent path
- */
- strcpy (Fullpath, &ParentPath[Index]);
- /*
- * Add dot separator
- * (don't need dot if parent fullpath is a single backslash)
- */
- if (ParentPath[1])
- {
- strcat (Fullpath, ".");
- }
- /* Copy child path (carat parent prefix(es) were skipped above) */
- strcat (Fullpath, Path);
- Cleanup:
- ACPI_FREE (ParentPath);
- return (Fullpath);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmAddToExternalFileList
- *
- * PARAMETERS: PathList - Single path or list separated by comma
- *
- * RETURN: None
- *
- * DESCRIPTION: Add external files to global list
- *
- ******************************************************************************/
- ACPI_STATUS
- AcpiDmAddToExternalFileList (
- char *Pathname)
- {
- ACPI_EXTERNAL_FILE *ExternalFile;
- char *LocalPathname;
- if (!Pathname)
- {
- return (AE_OK);
- }
- LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
- if (!LocalPathname)
- {
- return (AE_NO_MEMORY);
- }
- ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
- if (!ExternalFile)
- {
- ACPI_FREE (LocalPathname);
- return (AE_NO_MEMORY);
- }
- /* Take a copy of the file pathname */
- strcpy (LocalPathname, Pathname);
- ExternalFile->Path = LocalPathname;
- if (AcpiGbl_ExternalFileList)
- {
- ExternalFile->Next = AcpiGbl_ExternalFileList;
- }
- AcpiGbl_ExternalFileList = ExternalFile;
- return (AE_OK);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmClearExternalFileList
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Clear the external file list
- *
- ******************************************************************************/
- void
- AcpiDmClearExternalFileList (
- void)
- {
- ACPI_EXTERNAL_FILE *NextExternal;
- while (AcpiGbl_ExternalFileList)
- {
- NextExternal = AcpiGbl_ExternalFileList->Next;
- ACPI_FREE (AcpiGbl_ExternalFileList->Path);
- ACPI_FREE (AcpiGbl_ExternalFileList);
- AcpiGbl_ExternalFileList = NextExternal;
- }
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmGetExternalsFromFile
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Process the optional external reference file.
- *
- * Each line in the file should be of the form:
- * External (<Method namepath>, MethodObj, <ArgCount>)
- *
- * Example:
- * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
- *
- ******************************************************************************/
- void
- AcpiDmGetExternalsFromFile (
- void)
- {
- FILE *ExternalRefFile;
- char *Token;
- char *MethodName;
- UINT32 ArgCount;
- UINT32 ImportCount = 0;
- if (!Gbl_ExternalRefFilename)
- {
- return;
- }
- /* Open the file */
- ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
- if (!ExternalRefFile)
- {
- fprintf (stderr, "Could not open external reference file \"%s\"\n",
- Gbl_ExternalRefFilename);
- AslAbort ();
- return;
- }
- /* Each line defines a method */
- while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
- {
- Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */
- if (!Token)
- {
- continue;
- }
- if (strcmp (Token, "External"))
- {
- continue;
- }
- MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
- if (!MethodName)
- {
- continue;
- }
- Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
- if (!Token)
- {
- continue;
- }
- if (strcmp (Token, "MethodObj"))
- {
- continue;
- }
- Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
- if (!Token)
- {
- continue;
- }
- /* Convert arg count string to an integer */
- errno = 0;
- ArgCount = strtoul (Token, NULL, 0);
- if (errno)
- {
- fprintf (stderr, "Invalid argument count (%s)\n", Token);
- continue;
- }
- if (ArgCount > 7)
- {
- fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
- continue;
- }
- /* Add this external to the global list */
- AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
- Gbl_ExternalRefFilename, ArgCount, MethodName);
- AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
- ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
- ImportCount++;
- }
- if (!ImportCount)
- {
- fprintf (stderr,
- "Did not find any external methods in reference file \"%s\"\n",
- Gbl_ExternalRefFilename);
- }
- else
- {
- /* Add the external(s) to the namespace */
- AcpiDmAddExternalsToNamespace ();
- AcpiOsPrintf ("%s: Imported %u external method definitions\n",
- Gbl_ExternalRefFilename, ImportCount);
- }
- fclose (ExternalRefFile);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmAddOpToExternalList
- *
- * PARAMETERS: Op - Current parser Op
- * Path - Internal (AML) path to the object
- * Type - ACPI object type to be added
- * Value - Arg count if adding a Method object
- * Flags - To be passed to the external object
- *
- * RETURN: None
- *
- * DESCRIPTION: Insert a new name into the global list of Externals which
- * will in turn be later emitted as an External() declaration
- * in the disassembled output.
- *
- * This function handles the most common case where the referenced
- * name is simply not found in the constructed namespace.
- *
- ******************************************************************************/
- void
- AcpiDmAddOpToExternalList (
- ACPI_PARSE_OBJECT *Op,
- char *Path,
- UINT8 Type,
- UINT32 Value,
- UINT16 Flags)
- {
- char *ExternalPath;
- char *InternalPath = Path;
- char *Temp;
- ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
- if (!Path)
- {
- return_VOID;
- }
- /* Remove a root backslash if present */
- if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
- {
- Path++;
- }
- /* Externalize the pathname */
- Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
- NULL, &ExternalPath);
- if (ACPI_FAILURE (Status))
- {
- return_VOID;
- }
- /*
- * Get the full pathname from the root if "Path" has one or more
- * parent prefixes (^). Note: path will not contain a leading '\'.
- */
- if (*Path == (UINT8) AML_PARENT_PREFIX)
- {
- Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
- /* Set new external path */
- ACPI_FREE (ExternalPath);
- ExternalPath = Temp;
- if (!Temp)
- {
- return_VOID;
- }
- /* Create the new internal pathname */
- Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
- Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
- if (ACPI_FAILURE (Status))
- {
- ACPI_FREE (ExternalPath);
- return_VOID;
- }
- }
- /* Create the new External() declaration node */
- Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
- Type, Value, Flags);
- if (ACPI_FAILURE (Status))
- {
- ACPI_FREE (ExternalPath);
- if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
- {
- ACPI_FREE (InternalPath);
- }
- }
- return_VOID;
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmAddNodeToExternalList
- *
- * PARAMETERS: Node - Namespace node for object to be added
- * Type - ACPI object type to be added
- * Value - Arg count if adding a Method object
- * Flags - To be passed to the external object
- *
- * RETURN: None
- *
- * DESCRIPTION: Insert a new name into the global list of Externals which
- * will in turn be later emitted as an External() declaration
- * in the disassembled output.
- *
- * This function handles the case where the referenced name has
- * been found in the namespace, but the name originated in a
- * table other than the one that is being disassembled (such
- * as a table that is added via the iASL -e option).
- *
- ******************************************************************************/
- void
- AcpiDmAddNodeToExternalList (
- ACPI_NAMESPACE_NODE *Node,
- UINT8 Type,
- UINT32 Value,
- UINT16 Flags)
- {
- char *ExternalPath;
- char *InternalPath;
- char *Temp;
- ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
- if (!Node)
- {
- return_VOID;
- }
- /* Get the full external and internal pathnames to the node */
- ExternalPath = AcpiNsGetExternalPathname (Node);
- if (!ExternalPath)
- {
- return_VOID;
- }
- Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
- if (ACPI_FAILURE (Status))
- {
- ACPI_FREE (ExternalPath);
- return_VOID;
- }
- /* Remove the root backslash */
- if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1]))
- {
- Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1);
- if (!Temp)
- {
- return_VOID;
- }
- strcpy (Temp, &ExternalPath[1]);
- ACPI_FREE (ExternalPath);
- ExternalPath = Temp;
- }
- /* Create the new External() declaration node */
- Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
- Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
- if (ACPI_FAILURE (Status))
- {
- ACPI_FREE (ExternalPath);
- ACPI_FREE (InternalPath);
- }
- return_VOID;
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmAddPathToExternalList
- *
- * PARAMETERS: Path - External name of the object to be added
- * Type - ACPI object type to be added
- * Value - Arg count if adding a Method object
- * Flags - To be passed to the external object
- *
- * RETURN: None
- *
- * DESCRIPTION: Insert a new name into the global list of Externals which
- * will in turn be later emitted as an External() declaration
- * in the disassembled output.
- *
- * This function currently is used to add externals via a
- * reference file (via the -fe iASL option).
- *
- ******************************************************************************/
- static void
- AcpiDmAddPathToExternalList (
- char *Path,
- UINT8 Type,
- UINT32 Value,
- UINT16 Flags)
- {
- char *InternalPath;
- char *ExternalPath;
- ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
- if (!Path)
- {
- return_VOID;
- }
- /* Remove a root backslash if present */
- if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
- {
- Path++;
- }
- /* Create the internal and external pathnames */
- Status = AcpiNsInternalizeName (Path, &InternalPath);
- if (ACPI_FAILURE (Status))
- {
- return_VOID;
- }
- Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
- NULL, &ExternalPath);
- if (ACPI_FAILURE (Status))
- {
- ACPI_FREE (InternalPath);
- return_VOID;
- }
- /* Create the new External() declaration node */
- Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
- Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
- if (ACPI_FAILURE (Status))
- {
- ACPI_FREE (ExternalPath);
- ACPI_FREE (InternalPath);
- }
- return_VOID;
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmCreateNewExternal
- *
- * PARAMETERS: ExternalPath - External path to the object
- * InternalPath - Internal (AML) path to the object
- * Type - ACPI object type to be added
- * Value - Arg count if adding a Method object
- * Flags - To be passed to the external object
- *
- * RETURN: Status
- *
- * DESCRIPTION: Common low-level function to insert a new name into the global
- * list of Externals which will in turn be later emitted as
- * External() declarations in the disassembled output.
- *
- * Note: The external name should not include a root prefix
- * (backslash). We do not want External() statements to contain
- * a leading '\', as this prevents duplicate external statements
- * of the form:
- *
- * External (\ABCD)
- * External (ABCD)
- *
- * This would cause a compile time error when the disassembled
- * output file is recompiled.
- *
- * There are two cases that are handled here. For both, we emit
- * an External() statement:
- * 1) The name was simply not found in the namespace.
- * 2) The name was found, but it originated in a table other than
- * the table that is being disassembled.
- *
- ******************************************************************************/
- static ACPI_STATUS
- AcpiDmCreateNewExternal (
- char *ExternalPath,
- char *InternalPath,
- UINT8 Type,
- UINT32 Value,
- UINT16 Flags)
- {
- ACPI_EXTERNAL_LIST *NewExternal;
- ACPI_EXTERNAL_LIST *NextExternal;
- ACPI_EXTERNAL_LIST *PrevExternal = NULL;
- ACPI_FUNCTION_TRACE (DmCreateNewExternal);
- /* Check all existing externals to ensure no duplicates */
- NextExternal = AcpiGbl_ExternalList;
- while (NextExternal)
- {
- /* Check for duplicates */
- if (!strcmp (ExternalPath, NextExternal->Path))
- {
- /*
- * If this external came from an External() opcode, we are
- * finished with this one. (No need to check any further).
- */
- if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
- {
- return_ACPI_STATUS (AE_ALREADY_EXISTS);
- }
- /* Allow upgrade of type from ANY */
- else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
- (Type != ACPI_TYPE_ANY))
- {
- NextExternal->Type = Type;
- }
- /* Update the argument count as necessary */
- if (Value < NextExternal->Value)
- {
- NextExternal->Value = Value;
- }
- /* Update flags. */
- NextExternal->Flags |= Flags;
- NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
- return_ACPI_STATUS (AE_ALREADY_EXISTS);
- }
- NextExternal = NextExternal->Next;
- }
- /* Allocate and init a new External() descriptor */
- NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
- if (!NewExternal)
- {
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
- ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
- "Adding external reference node (%s) type [%s]\n",
- ExternalPath, AcpiUtGetTypeName (Type)));
- NewExternal->Flags = Flags;
- NewExternal->Value = Value;
- NewExternal->Path = ExternalPath;
- NewExternal->Type = Type;
- NewExternal->Length = (UINT16) strlen (ExternalPath);
- NewExternal->InternalPath = InternalPath;
- /* Link the new descriptor into the global list, alphabetically ordered */
- NextExternal = AcpiGbl_ExternalList;
- while (NextExternal)
- {
- if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
- {
- if (PrevExternal)
- {
- PrevExternal->Next = NewExternal;
- }
- else
- {
- AcpiGbl_ExternalList = NewExternal;
- }
- NewExternal->Next = NextExternal;
- return_ACPI_STATUS (AE_OK);
- }
- PrevExternal = NextExternal;
- NextExternal = NextExternal->Next;
- }
- if (PrevExternal)
- {
- PrevExternal->Next = NewExternal;
- }
- else
- {
- AcpiGbl_ExternalList = NewExternal;
- }
- return_ACPI_STATUS (AE_OK);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmAddExternalsToNamespace
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Add all externals to the namespace. Allows externals to be
- * "resolved".
- *
- ******************************************************************************/
- void
- AcpiDmAddExternalsToNamespace (
- void)
- {
- ACPI_STATUS Status;
- ACPI_NAMESPACE_NODE *Node;
- ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
- while (External)
- {
- /* Add the external name (object) into the namespace */
- Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
- ACPI_IMODE_LOAD_PASS1,
- ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
- NULL, &Node);
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "while adding external to namespace [%s]",
- External->Path));
- }
- else switch (External->Type)
- {
- case ACPI_TYPE_METHOD:
- /* For methods, we need to save the argument count */
- ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
- ObjDesc->Method.ParamCount = (UINT8) External->Value;
- Node->Object = ObjDesc;
- break;
- case ACPI_TYPE_REGION:
- /* Regions require a region sub-object */
- ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
- ObjDesc->Region.Node = Node;
- Node->Object = ObjDesc;
- break;
- default:
- break;
- }
- External = External->Next;
- }
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmGetExternalMethodCount
- *
- * PARAMETERS: None
- *
- * RETURN: The number of control method externals in the external list
- *
- * DESCRIPTION: Return the number of method externals that have been generated.
- * If any control method externals have been found, we must
- * re-parse the entire definition block with the new information
- * (number of arguments for the methods.) This is limitation of
- * AML, we don't know the number of arguments from the control
- * method invocation itself.
- *
- ******************************************************************************/
- UINT32
- AcpiDmGetExternalMethodCount (
- void)
- {
- ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
- UINT32 Count = 0;
- while (External)
- {
- if (External->Type == ACPI_TYPE_METHOD)
- {
- Count++;
- }
- External = External->Next;
- }
- return (Count);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmClearExternalList
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Free the entire External info list
- *
- ******************************************************************************/
- void
- AcpiDmClearExternalList (
- void)
- {
- ACPI_EXTERNAL_LIST *NextExternal;
- while (AcpiGbl_ExternalList)
- {
- NextExternal = AcpiGbl_ExternalList->Next;
- ACPI_FREE (AcpiGbl_ExternalList->Path);
- ACPI_FREE (AcpiGbl_ExternalList);
- AcpiGbl_ExternalList = NextExternal;
- }
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmEmitExternals
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Emit an External() ASL statement for each of the externals in
- * the global external info list.
- *
- ******************************************************************************/
- void
- AcpiDmEmitExternals (
- void)
- {
- ACPI_EXTERNAL_LIST *NextExternal;
- if (!AcpiGbl_ExternalList)
- {
- return;
- }
- /*
- * Determine the number of control methods in the external list, and
- * also how many of those externals were resolved via the namespace.
- */
- NextExternal = AcpiGbl_ExternalList;
- while (NextExternal)
- {
- if (NextExternal->Type == ACPI_TYPE_METHOD)
- {
- AcpiGbl_NumExternalMethods++;
- if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
- {
- AcpiGbl_ResolvedExternalMethods++;
- }
- }
- NextExternal = NextExternal->Next;
- }
- /* Check if any control methods were unresolved */
- AcpiDmUnresolvedWarning (1);
- if (Gbl_ExternalRefFilename)
- {
- AcpiOsPrintf (
- " /*\n * External declarations were imported from\n"
- " * a reference file -- %s\n */\n\n",
- Gbl_ExternalRefFilename);
- }
- /*
- * Walk and emit the list of externals found during the AML parsing
- */
- while (AcpiGbl_ExternalList)
- {
- if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
- {
- AcpiOsPrintf (" External (%s%s)",
- AcpiGbl_ExternalList->Path,
- AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
- /* Check for "unresolved" method reference */
- if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
- (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
- {
- AcpiOsPrintf (" // Warning: Unknown method, "
- "guessing %u arguments",
- AcpiGbl_ExternalList->Value);
- }
- /* Check for external from a external references file */
- else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
- {
- if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
- {
- AcpiOsPrintf (" // %u Arguments",
- AcpiGbl_ExternalList->Value);
- }
- AcpiOsPrintf (" // From external reference file");
- }
- /* This is the normal external case */
- else
- {
- /* For methods, add a comment with the number of arguments */
- if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
- {
- AcpiOsPrintf (" // %u Arguments",
- AcpiGbl_ExternalList->Value);
- }
- }
- AcpiOsPrintf ("\n");
- }
- /* Free this external info block and move on to next external */
- NextExternal = AcpiGbl_ExternalList->Next;
- if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
- {
- ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
- }
- ACPI_FREE (AcpiGbl_ExternalList->Path);
- ACPI_FREE (AcpiGbl_ExternalList);
- AcpiGbl_ExternalList = NextExternal;
- }
- AcpiOsPrintf ("\n");
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDmUnresolvedWarning
- *
- * PARAMETERS: Type - Where to output the warning.
- * 0 means write to stderr
- * 1 means write to AcpiOsPrintf
- *
- * RETURN: None
- *
- * DESCRIPTION: Issue warning message if there are unresolved external control
- * methods within the disassembly.
- *
- ******************************************************************************/
- #if 0
- Summary of the external control method problem:
- When the -e option is used with disassembly, the various SSDTs are simply
- loaded into a global namespace for the disassembler to use in order to
- resolve control method references (invocations).
- The disassembler tracks any such references, and will emit an External()
- statement for these types of methods, with the proper number of arguments .
- Without the SSDTs, the AML does not contain enough information to properly
- disassemble the control method invocation -- because the disassembler does
- not know how many arguments to parse.
- An example: Assume we have two control methods. ABCD has one argument, and
- EFGH has zero arguments. Further, we have two additional control methods
- that invoke ABCD and EFGH, named T1 and T2:
- Method (ABCD, 1)
- {
- }
- Method (EFGH, 0)
- {
- }
- Method (T1)
- {
- ABCD (Add (2, 7, Local0))
- }
- Method (T2)
- {
- EFGH ()
- Add (2, 7, Local0)
- }
- Here is the AML code that is generated for T1 and T2:
- 185: Method (T1)
- 0000034C: 14 10 54 31 5F 5F 00 ... "..T1__."
- 186: {
- 187: ABCD (Add (2, 7, Local0))
- 00000353: 41 42 43 44 ............ "ABCD"
- 00000357: 72 0A 02 0A 07 60 ...... "r....`"
- 188: }
- 190: Method (T2)
- 0000035D: 14 10 54 32 5F 5F 00 ... "..T2__."
- 191: {
- 192: EFGH ()
- 00000364: 45 46 47 48 ............ "EFGH"
- 193: Add (2, 7, Local0)
- 00000368: 72 0A 02 0A 07 60 ...... "r....`"
- 194: }
- Note that the AML code for T1 and T2 is essentially identical. When
- disassembling this code, the methods ABCD and EFGH must be known to the
- disassembler, otherwise it does not know how to handle the method invocations.
- In other words, if ABCD and EFGH are actually external control methods
- appearing in an SSDT, the disassembler does not know what to do unless
- the owning SSDT has been loaded via the -e option.
- #endif
- static char ExternalWarningPart1[600];
- static char ExternalWarningPart2[400];
- static char ExternalWarningPart3[400];
- static char ExternalWarningPart4[200];
- void
- AcpiDmUnresolvedWarning (
- UINT8 Type)
- {
- char *Format;
- char Pad[] = " *";
- char NoPad[] = "";
- if (!AcpiGbl_NumExternalMethods)
- {
- return;
- }
- if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
- {
- return;
- }
- Format = Type ? Pad : NoPad;
- sprintf (ExternalWarningPart1,
- "%s iASL Warning: There %s %u external control method%s found during\n"
- "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
- "%s ACPI tables may be required to properly disassemble the code. This\n"
- "%s resulting disassembler output file may not compile because the\n"
- "%s disassembler did not know how many arguments to assign to the\n"
- "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
- "%s runtime and may or may not be available via the host OS.\n",
- Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
- AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
- Format, AcpiGbl_ResolvedExternalMethods,
- (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
- (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
- Format, Format, Format, Format, Format);
- sprintf (ExternalWarningPart2,
- "%s To specify the tables needed to resolve external control method\n"
- "%s references, the -e option can be used to specify the filenames.\n"
- "%s Example iASL invocations:\n"
- "%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
- "%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
- "%s iasl -e ssdt*.aml -d dsdt.aml\n",
- Format, Format, Format, Format, Format, Format);
- sprintf (ExternalWarningPart3,
- "%s In addition, the -fe option can be used to specify a file containing\n"
- "%s control method external declarations with the associated method\n"
- "%s argument counts. Each line of the file must be of the form:\n"
- "%s External (<method pathname>, MethodObj, <argument count>)\n"
- "%s Invocation:\n"
- "%s iasl -fe refs.txt -d dsdt.aml\n",
- Format, Format, Format, Format, Format, Format);
- sprintf (ExternalWarningPart4,
- "%s The following methods were unresolved and many not compile properly\n"
- "%s because the disassembler had to guess at the number of arguments\n"
- "%s required for each:\n",
- Format, Format, Format);
- if (Type)
- {
- if (!AcpiGbl_ExternalFileList)
- {
- /* The -e option was not specified */
- AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n",
- ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
- ExternalWarningPart4);
- }
- else
- {
- /* The -e option was specified, but there are still some unresolved externals */
- AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n",
- ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
- }
- }
- else
- {
- if (!AcpiGbl_ExternalFileList)
- {
- /* The -e option was not specified */
- fprintf (stderr, "\n%s\n%s\n%s\n",
- ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
- }
- else
- {
- /* The -e option was specified, but there are still some unresolved externals */
- fprintf (stderr, "\n%s\n%s\n",
- ExternalWarningPart1, ExternalWarningPart3);
- }
- }
- }
|