Disassembler: Restructure code for externals, no functional change.

Add new file for handling of ASL External() statements. Consolidates
all such code, it is used only for iASL disassembler (not kernel code
or acpiexec.)
This commit is contained in:
Robert Moore 2009-10-01 13:33:07 -07:00
parent c13698fbed
commit ecea3cc012
11 changed files with 741 additions and 496 deletions

View File

@ -71,6 +71,7 @@ SRCS= aslcompilerparse.c aslcompilerlex.c aslanalyze.c aslcodegen.c \
../common/adfile.c \
../common/adisasm.c \
../common/adwalk.c \
../common/dmextern.c \
../common/dmrestag.c \
../common/dmtable.c \
../common/dmtbinfo.c \

View File

@ -326,6 +326,10 @@ SOURCE=..\..\source\common\adwalk.c
# End Source File
# Begin Source File
SOURCE=..\..\source\common\dmextern.c
# End Source File
# Begin Source File
SOURCE=..\..\source\common\dmrestag.c
# End Source File
# Begin Source File

View File

@ -42,6 +42,7 @@ OBJS = \
aslutils.o \
dbfileio.o \
dmbuffer.o \
dmextern.o \
dmnames.o \
dmobject.o \
dmopcode.o \
@ -247,6 +248,9 @@ adisasm.o : $(ACPICA_COMMON)/adisasm.c
adwalk.o : $(ACPICA_COMMON)/adwalk.c
$(COMPILE)
dmextern.o : $(ACPICA_COMMON)/dmextern.c
$(COMPILE)
dmrestag.o : $(ACPICA_COMMON)/dmrestag.c
$(COMPILE)

View File

@ -153,14 +153,6 @@ void
AdDisassemblerHeader (
char *Filename);
void
AdAddExternalsToNamespace (
void);
UINT32
AdMethodExternalCount (
void);
ACPI_STATUS
AdDeferredParse (
ACPI_PARSE_OBJECT *Op,
@ -296,93 +288,6 @@ AdInitialize (
}
/*******************************************************************************
*
* FUNCTION: AdAddExternalsToNamespace
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Add all externals to the namespace. Allows externals to be
* "resolved".
*
******************************************************************************/
void
AdAddExternalsToNamespace (
void)
{
ACPI_STATUS Status;
ACPI_NAMESPACE_NODE *Node;
ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
ACPI_OPERAND_OBJECT *MethodDesc;
ACPI_FUNCTION_NAME (AdAddExternalsToNamespace );
while (External)
{
/* Add the external name (object) into the namespace */
Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
ACPI_IMODE_LOAD_PASS1, 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 if (External->Type == ACPI_TYPE_METHOD)
{
/* For methods, we need to save the argument count */
MethodDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
MethodDesc->Method.ParamCount = (UINT8) External->Value;
Node->Object = MethodDesc;
}
External = External->Next;
}
}
/*******************************************************************************
*
* FUNCTION: AdMethodExternalCount
*
* PARAMETERS: None
*
* RETURN: The number of control method externals in the external list
*
* DESCRIPTION: Return the number of externals that have been generated
*
******************************************************************************/
UINT32
AdMethodExternalCount (
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: AdAmlDisassemble
@ -416,7 +321,6 @@ AdAmlDisassemble (
ACPI_TABLE_HEADER *Table = NULL;
ACPI_TABLE_HEADER *ExternalTable;
ACPI_OWNER_ID OwnerId;
ACPI_EXTERNAL_LIST *NextExternal;
/*
@ -475,13 +379,7 @@ AdAmlDisassemble (
/* Clear external list generated by Scope in external tables */
while (AcpiGbl_ExternalList)
{
NextExternal = AcpiGbl_ExternalList->Next;
ACPI_FREE (AcpiGbl_ExternalList->Path);
ACPI_FREE (AcpiGbl_ExternalList);
AcpiGbl_ExternalList = NextExternal;
}
AcpiDmClearExternalList ();
}
}
else
@ -602,11 +500,11 @@ AdAmlDisassemble (
* tree with the new information (namely, the number of arguments per
* method)
*/
if (AdMethodExternalCount ())
if (AcpiDmGetExternalMethodCount ())
{
fprintf (stderr,
"\nFound %d external control methods, reparsing with new information\n",
AdMethodExternalCount());
AcpiDmGetExternalMethodCount ());
/*
* Reparse, rebuild namespace. no need to xref namespace
@ -624,7 +522,7 @@ AdAmlDisassemble (
AcpiGbl_RootNodeStruct.Flags = ANOBJ_END_OF_PEER_LIST;
Status = AcpiNsRootInitialize ();
AdAddExternalsToNamespace ();
AcpiDmAddExternalsToNamespace ();
/* Parse table. No need to reload it, however (FALSE) */

646
source/common/dmextern.c Normal file
View File

@ -0,0 +1,646 @@
/******************************************************************************
*
* Module Name: dmextern - Support for External() ASL statements
*
*****************************************************************************/
/******************************************************************************
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2009, 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"
/*
* 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 */ "", /* 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"
};
/* Local prototypes */
static const char *
AcpiDmGetObjectTypeName (
ACPI_OBJECT_TYPE Type);
static char *
AcpiDmNormalizeParentPrefix (
ACPI_PARSE_OBJECT *Op,
char *Path);
/*******************************************************************************
*
* 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;
/* Search upwards in the parse tree until we reach a namespace node */
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 = AcpiNsGetParentNode (Node);
Path++;
}
if (!Node)
{
return (NULL);
}
/* Get the full pathname for the parent node */
ParentPath = AcpiNsGetExternalPathname (Node);
if (!ParentPath)
{
return (NULL);
}
Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 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
*/
ACPI_STRCAT (Fullpath, ParentPath);
/* Add dot separator (don't need dot if parent fullpath is a single "\") */
if (ParentPath[1])
{
ACPI_STRCAT (Fullpath, ".");
}
/* Copy child path (carat parent prefix(es) were skipped above) */
ACPI_STRCAT (Fullpath, Path);
Cleanup:
ACPI_FREE (ParentPath);
return (Fullpath);
}
/*******************************************************************************
*
* FUNCTION: AcpiDmAddToExternalList
*
* 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
*
* 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.
*
******************************************************************************/
void
AcpiDmAddToExternalList (
ACPI_PARSE_OBJECT *Op,
char *Path,
UINT8 Type,
UINT32 Value)
{
char *ExternalPath;
char *Fullpath = NULL;
ACPI_EXTERNAL_LIST *NewExternal;
ACPI_EXTERNAL_LIST *NextExternal;
ACPI_EXTERNAL_LIST *PrevExternal = NULL;
ACPI_STATUS Status;
if (!Path)
{
return;
}
/* Externalize the ACPI path */
Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
NULL, &ExternalPath);
if (ACPI_FAILURE (Status))
{
return;
}
/* Get the full pathname from root if "Path" has a parent prefix */
if (*Path == (UINT8) AML_PARENT_PREFIX)
{
Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
if (Fullpath)
{
/* Set new external path */
ACPI_FREE (ExternalPath);
ExternalPath = Fullpath;
}
}
/* Check all existing externals to ensure no duplicates */
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
if (!ACPI_STRCMP (ExternalPath, NextExternal->Path))
{
/* Duplicate method, check that the Value (ArgCount) is the same */
if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
(NextExternal->Value != Value))
{
ACPI_ERROR ((AE_INFO,
"Argument count mismatch for method %s %d %d",
NextExternal->Path, NextExternal->Value, Value));
}
/* Allow upgrade of type from ANY */
else if (NextExternal->Type == ACPI_TYPE_ANY)
{
NextExternal->Type = Type;
NextExternal->Value = Value;
}
ACPI_FREE (ExternalPath);
return;
}
NextExternal = NextExternal->Next;
}
/* Allocate and init a new External() descriptor */
NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
if (!NewExternal)
{
ACPI_FREE (ExternalPath);
return;
}
NewExternal->Path = ExternalPath;
NewExternal->Type = Type;
NewExternal->Value = Value;
NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath);
/* Was the external path with parent prefix normalized to a fullpath? */
if (Fullpath == ExternalPath)
{
/* Get new internal path */
Status = AcpiNsInternalizeName (ExternalPath, &Path);
if (ACPI_FAILURE (Status))
{
ACPI_FREE (ExternalPath);
ACPI_FREE (NewExternal);
return;
}
/* Set flag to indicate External->InternalPath need to be freed */
NewExternal->Flags |= ACPI_IPATH_ALLOCATED;
}
NewExternal->InternalPath = Path;
/* Link the new descriptor into the global list, ordered by string length */
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
if (NewExternal->Length <= NextExternal->Length)
{
if (PrevExternal)
{
PrevExternal->Next = NewExternal;
}
else
{
AcpiGbl_ExternalList = NewExternal;
}
NewExternal->Next = NextExternal;
return;
}
PrevExternal = NextExternal;
NextExternal = NextExternal->Next;
}
if (PrevExternal)
{
PrevExternal->Next = NewExternal;
}
else
{
AcpiGbl_ExternalList = NewExternal;
}
}
/*******************************************************************************
*
* 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 *MethodDesc;
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_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 if (External->Type == ACPI_TYPE_METHOD)
{
/* For methods, we need to save the argument count */
MethodDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
MethodDesc->Method.ParamCount = (UINT8) External->Value;
Node->Object = MethodDesc;
}
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;
}
/*
* Walk the list of externals (unresolved references)
* found during the AML parsing
*/
while (AcpiGbl_ExternalList)
{
AcpiOsPrintf (" External (%s%s",
AcpiGbl_ExternalList->Path,
AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
{
AcpiOsPrintf (") // %d Arguments\n",
AcpiGbl_ExternalList->Value);
}
else
{
AcpiOsPrintf (")\n");
}
/* Free this external info block and move on to next external */
NextExternal = AcpiGbl_ExternalList->Next;
if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED)
{
ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
}
ACPI_FREE (AcpiGbl_ExternalList->Path);
ACPI_FREE (AcpiGbl_ExternalList);
AcpiGbl_ExternalList = NextExternal;
}
AcpiOsPrintf ("\n");
}

View File

@ -129,9 +129,6 @@
ACPI_MODULE_NAME ("dmutils")
ACPI_EXTERNAL_LIST *AcpiGbl_ExternalList = NULL;
/* Data used in keeping track of fields */
#if 0
const char *AcpiGbl_FENames[] =
@ -202,255 +199,6 @@ const char *AcpiGbl_IrqDecode[] =
};
#ifdef ACPI_ASL_COMPILER
/*******************************************************************************
*
* FUNCTION: AcpiDmNormalizeParentPrefix
*
* PARAMETERS: Op - Parse op
* Path - Path with parent prefix
*
* RETURN: The full pathname to the object (from the namespace root)
*
* DESCRIPTION: Return 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)
{
char *ParentPath;
char *Fullpath = NULL;
UINT32 Length;
ACPI_NAMESPACE_NODE *Node = NULL;
/* Go upwards in the parse tree until we reach a namespace node */
while (Op)
{
if (Op->Common.Node)
{
break;
}
Op = Op->Common.Parent;
}
/* Remove all carats from the input path */
if (Op)
{
Node = Op->Common.Node;
/*
* There may be multiple parent prefixes
* For example, ^^^M000
*/
while (Node && *Path == (UINT8) AML_PARENT_PREFIX)
{
Node = AcpiNsGetParentNode (Node);
Path++;
}
}
if (Node)
{
/* Get the full pathname for the parent node */
ParentPath = AcpiNsGetExternalPathname (Node);
if (ParentPath)
{
Length = ACPI_STRLEN (ParentPath);
Length += ACPI_STRLEN (Path) + 1;
Fullpath = ACPI_ALLOCATE_ZEROED (Length);
/*
* Concatenate parent fullpath and path. For example,
* Parent fullpath "\_SB_", path "^INIT"
* Fullpath "\_SB_.INIT"
*/
if (Fullpath)
{
/* Copy parent path */
ACPI_STRCAT (Fullpath, ParentPath);
/* Don't need "." if parent fullpath is a single "\" */
if (ParentPath[1])
{
ACPI_STRCAT (Fullpath, ".");
}
/* Copy child path, ^ parent prefix was skipped already */
ACPI_STRCAT (Fullpath, Path);
}
ACPI_FREE (ParentPath);
}
}
return (Fullpath);
}
/*******************************************************************************
*
* FUNCTION: AcpiDmAddToExternalList
*
* PARAMETERS: Path - Internal (AML) path to the object
*
* RETURN: None
*
* DESCRIPTION: Insert a new path into the list of Externals which will in
* turn be emitted as an External() declaration in the disassembled
* output.
*
******************************************************************************/
void
AcpiDmAddToExternalList (
ACPI_PARSE_OBJECT *Op,
char *Path,
UINT8 Type,
UINT32 Value)
{
char *ExternalPath;
char *Fullpath = NULL;
ACPI_EXTERNAL_LIST *NewExternal;
ACPI_EXTERNAL_LIST *NextExternal;
ACPI_EXTERNAL_LIST *PrevExternal = NULL;
ACPI_STATUS Status;
if (!Path)
{
return;
}
/* Externalize the ACPI path */
Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
NULL, &ExternalPath);
if (ACPI_FAILURE (Status))
{
return;
}
/* Get the fullpath if "Path" has a parent prefix */
if (*Path == (UINT8) AML_PARENT_PREFIX)
{
Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
if (Fullpath)
{
/* Set new external path */
ACPI_FREE (ExternalPath);
ExternalPath = Fullpath;
}
}
/* Ensure that we don't have duplicate externals */
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
/* Allow upgrade of type from ANY */
if (!ACPI_STRCMP (ExternalPath, NextExternal->Path))
{
/* Duplicate method, check that the Value (ArgCount) is the same */
if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
(NextExternal->Value != Value))
{
ACPI_ERROR ((AE_INFO, "Argument count mismatch for method %s %d %d",
NextExternal->Path, NextExternal->Value, Value));
}
if (NextExternal->Type == ACPI_TYPE_ANY)
{
NextExternal->Type = Type;
NextExternal->Value = Value;
}
ACPI_FREE (ExternalPath);
return;
}
NextExternal = NextExternal->Next;
}
/* Allocate and init a new External() descriptor */
NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
NewExternal->Path = ExternalPath;
NewExternal->Type = Type;
NewExternal->Value = Value;
NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath);
/* Was the external path with parent prefix normalized to fullpath? */
if (Fullpath == ExternalPath)
{
/* Get new internal path */
Status = AcpiNsInternalizeName (ExternalPath, &Path);
if (ACPI_FAILURE (Status))
{
ACPI_FREE (ExternalPath);
ACPI_FREE (NewExternal);
return;
}
/* Set flag to indicate External->InternalPath need to be freed */
NewExternal->Flags |= ACPI_IPATH_ALLOCATED;
}
NewExternal->InternalPath = Path;
/* Link the new descriptor into the global list, ordered by string length */
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
if (NewExternal->Length <= NextExternal->Length)
{
if (PrevExternal)
{
PrevExternal->Next = NewExternal;
}
else
{
AcpiGbl_ExternalList = NewExternal;
}
NewExternal->Next = NextExternal;
return;
}
PrevExternal = NextExternal;
NextExternal = NextExternal->Next;
}
if (PrevExternal)
{
PrevExternal->Next = NewExternal;
}
else
{
AcpiGbl_ExternalList = NewExternal;
}
}
#endif
/*******************************************************************************
*
* FUNCTION: AcpiDmDecodeAttribute

View File

@ -130,6 +130,17 @@
#define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: "
/* Stub for non-compiler code */
#ifndef ACPI_ASL_COMPILER
void
AcpiDmEmitExternals (
void)
{
return;
}
#endif
/* Local prototypes */
static ACPI_STATUS
@ -148,68 +159,6 @@ static UINT32
AcpiDmBlockType (
ACPI_PARSE_OBJECT *Op);
static const char *
AcpiDmGetObjectTypeName (
ACPI_OBJECT_TYPE Type);
/*
* This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
* ObjectTypeKeyword. Used to generate typed external declarations
*/
static const char *AcpiGbl_DmTypeNames[] =
{
/* 00 */ "", /* 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"
};
/*******************************************************************************
*
* 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]);
}
/*******************************************************************************
@ -522,7 +471,6 @@ AcpiDmDescendingOp (
const ACPI_OPCODE_INFO *OpInfo;
UINT32 Name;
ACPI_PARSE_OBJECT *NextOp;
ACPI_EXTERNAL_LIST *NextExternal;
if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
@ -554,41 +502,7 @@ AcpiDmDescendingOp (
/* Emit all External() declarations here */
if (AcpiGbl_ExternalList)
{
/*
* Walk the list of externals (unresolved references)
* found during parsing
*/
while (AcpiGbl_ExternalList)
{
AcpiOsPrintf (" External (%s%s",
AcpiGbl_ExternalList->Path,
AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
{
AcpiOsPrintf (") // %d Arguments\n", AcpiGbl_ExternalList->Value);
}
else
{
AcpiOsPrintf (")\n");
}
/* Free this external info and move on to next external */
NextExternal = AcpiGbl_ExternalList->Next;
if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED)
{
ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
}
ACPI_FREE (AcpiGbl_ExternalList->Path);
ACPI_FREE (AcpiGbl_ExternalList);
AcpiGbl_ExternalList = NextExternal;
}
AcpiOsPrintf ("\n");
}
AcpiDmEmitExternals ();
return (AE_OK);
}
}

View File

@ -949,6 +949,10 @@ AcpiUtInitGlobals (
AcpiGbl_RootNodeStruct.Flags = ANOBJ_END_OF_PEER_LIST;
#ifdef ACPI_DISASSEMBLER
AcpiGbl_ExternalList = NULL;
#endif
#ifdef ACPI_DEBUG_OUTPUT
AcpiGbl_LowestStackPointer = ACPI_CAST_PTR (ACPI_SIZE, ACPI_SIZE_MAX);
#endif

View File

@ -125,25 +125,6 @@
#define BLOCK_COMMA_LIST 4
#define ACPI_DEFAULT_RESNAME *(UINT32 *) "__RD"
typedef struct acpi_external_list
{
char *Path;
char *InternalPath;
struct acpi_external_list *Next;
UINT32 Value;
UINT16 Length;
UINT8 Type;
UINT8 Flags;
} ACPI_EXTERNAL_LIST;
/* Values for Flags field above */
#define ACPI_IPATH_ALLOCATED 0x01
/* List of externals generated during disassembly */
extern ACPI_EXTERNAL_LIST *AcpiGbl_ExternalList;
typedef const struct acpi_dmtable_info
{
@ -482,14 +463,6 @@ void
AcpiDmMatchOp (
ACPI_PARSE_OBJECT *Op);
BOOLEAN
AcpiDmCommaIfListMember (
ACPI_PARSE_OBJECT *Op);
void
AcpiDmCommaIfFieldMember (
ACPI_PARSE_OBJECT *Op);
/*
* dmnames
@ -562,6 +535,33 @@ AcpiDmIsStringBuffer (
ACPI_PARSE_OBJECT *Op);
/*
* dmextern
*/
void
AcpiDmAddToExternalList (
ACPI_PARSE_OBJECT *Op,
char *Path,
UINT8 Type,
UINT32 Value);
void
AcpiDmAddExternalsToNamespace (
void);
UINT32
AcpiDmGetExternalMethodCount (
void);
void
AcpiDmClearExternalList (
void);
void
AcpiDmEmitExternals (
void);
/*
* dmresrc
*/
@ -596,18 +596,10 @@ ACPI_STATUS
AcpiDmIsResourceTemplate (
ACPI_PARSE_OBJECT *Op);
void
AcpiDmIndent (
UINT32 Level);
void
AcpiDmBitList (
UINT16 Mask);
void
AcpiDmDecodeAttribute (
UINT8 Attribute);
void
AcpiDmDescriptorName (
void);
@ -734,11 +726,21 @@ AcpiDmVendorSmallDescriptor (
* dmutils
*/
void
AcpiDmAddToExternalList (
ACPI_PARSE_OBJECT *Op,
char *Path,
UINT8 Type,
UINT32 Value);
AcpiDmDecodeAttribute (
UINT8 Attribute);
void
AcpiDmIndent (
UINT32 Level);
BOOLEAN
AcpiDmCommaIfListMember (
ACPI_PARSE_OBJECT *Op);
void
AcpiDmCommaIfFieldMember (
ACPI_PARSE_OBJECT *Op);
/*
* dmrestag

View File

@ -446,6 +446,7 @@ ACPI_EXTERN UINT8 AcpiGbl_DbOutputFlags;
ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_disasm;
ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_verbose;
ACPI_EXTERN ACPI_EXTERNAL_LIST *AcpiGbl_ExternalList;
#endif

View File

@ -1216,6 +1216,29 @@ typedef struct acpi_port_info
#define ACPI_ASCII_ZERO 0x30
/*****************************************************************************
*
* Disassembler
*
****************************************************************************/
typedef struct acpi_external_list
{
char *Path;
char *InternalPath;
struct acpi_external_list *Next;
UINT32 Value;
UINT16 Length;
UINT8 Type;
UINT8 Flags;
} ACPI_EXTERNAL_LIST;
/* Values for Flags field above */
#define ACPI_IPATH_ALLOCATED 0x01
/*****************************************************************************
*
* Debugger