summaryrefslogtreecommitdiffstats
path: root/source/components/disassembler
diff options
context:
space:
mode:
Diffstat (limited to 'source/components/disassembler')
-rw-r--r--source/components/disassembler/dmbuffer.c203
-rw-r--r--source/components/disassembler/dmcstyle.c773
-rw-r--r--source/components/disassembler/dmopcode.c38
-rw-r--r--source/components/disassembler/dmutils.c15
-rw-r--r--source/components/disassembler/dmwalk.c50
5 files changed, 1013 insertions, 66 deletions
diff --git a/source/components/disassembler/dmbuffer.c b/source/components/disassembler/dmbuffer.c
index 973e269..afb0842 100644
--- a/source/components/disassembler/dmbuffer.c
+++ b/source/components/disassembler/dmbuffer.c
@@ -79,6 +79,51 @@ AcpiDmPldBuffer (
#define ACPI_BUFFER_BYTES_PER_LINE 8
+/* Strings for ToPld */
+
+static char *DmPanelList[] =
+{
+ "TOP",
+ "BOTTOM",
+ "LEFT",
+ "RIGHT",
+ "FRONT",
+ "BACK",
+ "UNKNOWN",
+ NULL
+};
+
+static char *DmVerticalPositionList[] =
+{
+ "UPPER",
+ "CENTER",
+ "LOWER",
+ NULL
+};
+
+static char *DmHorizontalPositionList[] =
+{
+ "LEFT",
+ "CENTER",
+ "RIGHT",
+ NULL
+};
+
+static char *DmShapeList[] =
+{
+ "ROUND",
+ "OVAL",
+ "SQUARE",
+ "VERTICALRECTANGLE",
+ "HORIZONTALRECTANGLE",
+ "VERTICALTRAPEZOID",
+ "HORIZONTALTRAPEZOID",
+ "UNKNOWN",
+ "CHAMFERED",
+ NULL
+};
+
+
/*******************************************************************************
*
* FUNCTION: AcpiDmDisasmByteList
@@ -232,8 +277,9 @@ AcpiDmByteList (
break;
case ACPI_DASM_PLD_METHOD:
-
+#if 0
AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
+#endif
AcpiDmPldBuffer (Info->Level, ByteData, ByteCount);
break;
@@ -434,11 +480,12 @@ AcpiDmIsUnicodeBuffer (
return (FALSE);
}
- /* For each word, 1st byte must be ascii, 2nd byte must be zero */
+ /* For each word, 1st byte must be ascii (1-0x7F), 2nd byte must be zero */
for (i = 0; i < (ByteCount - 2); i += 2)
{
- if ((!ACPI_IS_PRINT (ByteData[i])) ||
+ if ((ByteData[i] == 0) ||
+ (ByteData[i] > 0x7F) ||
(ByteData[(ACPI_SIZE) i + 1] != 0))
{
return (FALSE);
@@ -534,9 +581,14 @@ AcpiDmIsPldBuffer (
ACPI_PARSE_OBJECT *Op)
{
ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *SizeOp;
ACPI_PARSE_OBJECT *ParentOp;
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
ParentOp = Op->Common.Parent;
if (!ParentOp)
{
@@ -551,6 +603,9 @@ AcpiDmIsPldBuffer (
if (ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__PLD))
{
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
return (TRUE);
}
@@ -573,6 +628,9 @@ AcpiDmIsPldBuffer (
if (ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__PLD))
{
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
return (TRUE);
}
}
@@ -584,6 +642,51 @@ AcpiDmIsPldBuffer (
/*******************************************************************************
*
+ * FUNCTION: AcpiDmFindNameByIndex
+ *
+ * PARAMETERS: Index - Index of array to check
+ * List - Array to reference
+ *
+ * RETURN: String from List or empty string
+ *
+ * DESCRIPTION: Finds and returns the char string located at the given index
+ * position in List.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiDmFindNameByIndex (
+ UINT64 Index,
+ char **List)
+{
+ char *Str;
+ UINT32 i;
+
+
+ /* Bounds check */
+
+ Str = List[0];
+ i = 0;
+
+ while(Str)
+ {
+ i++;
+ Str = List[i];
+ }
+
+ if (Index >= i)
+ {
+ /* TBD: Add error msg */
+
+ return ("");
+ }
+
+ return (List[Index]);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiDmPldBuffer
*
* PARAMETERS: Level - Current source code indentation level
@@ -596,9 +699,12 @@ AcpiDmIsPldBuffer (
*
******************************************************************************/
-#define ACPI_PLD_OUTPUT08 "%*.s/* %18s : %-6.2X */\n", ACPI_MUL_4 (Level), " "
-#define ACPI_PLD_OUTPUT16 "%*.s/* %18s : %-6.4X */\n", ACPI_MUL_4 (Level), " "
-#define ACPI_PLD_OUTPUT24 "%*.s/* %18s : %-6.6X */\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT08 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT08P "%*.s%-18s = 0x%X)\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT16 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT16P "%*.s%-18s = 0x%X)\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT24 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUTSTR "%*.s%-18s = \"%s\",\n", ACPI_MUL_4 (Level), " "
static void
AcpiDmPldBuffer (
@@ -625,47 +731,63 @@ AcpiDmPldBuffer (
return;
}
+ AcpiOsPrintf ("\n");
+
/* First 32-bit dword */
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Revision", PldInfo->Revision);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "IgnoreColor", PldInfo->IgnoreColor);
- AcpiOsPrintf (ACPI_PLD_OUTPUT24,"Color", PldInfo->Color);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Revision", PldInfo->Revision);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_IgnoreColor", PldInfo->IgnoreColor);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Red", PldInfo->Red);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Green", PldInfo->Green);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Blue", PldInfo->Blue);
/* Second 32-bit dword */
- AcpiOsPrintf (ACPI_PLD_OUTPUT16,"Width", PldInfo->Width);
- AcpiOsPrintf (ACPI_PLD_OUTPUT16,"Height", PldInfo->Height);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Width", PldInfo->Width);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Height", PldInfo->Height);
/* Third 32-bit dword */
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "UserVisible", PldInfo->UserVisible);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Dock", PldInfo->Dock);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Lid", PldInfo->Lid);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Panel", PldInfo->Panel);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "VerticalPosition", PldInfo->VerticalPosition);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "HorizontalPosition", PldInfo->HorizontalPosition);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Shape", PldInfo->Shape);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "GroupOrientation", PldInfo->GroupOrientation);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "GroupToken", PldInfo->GroupToken);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "GroupPosition", PldInfo->GroupPosition);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Bay", PldInfo->Bay);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_UserVisible", PldInfo->UserVisible);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Dock", PldInfo->Dock);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Lid", PldInfo->Lid);
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Panel",
+ AcpiDmFindNameByIndex(PldInfo->Panel, DmPanelList));
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_VerticalPosition",
+ AcpiDmFindNameByIndex(PldInfo->VerticalPosition, DmVerticalPositionList));
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_HorizontalPosition",
+ AcpiDmFindNameByIndex(PldInfo->HorizontalPosition, DmHorizontalPositionList));
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Shape",
+ AcpiDmFindNameByIndex(PldInfo->Shape, DmShapeList));
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupOrientation", PldInfo->GroupOrientation);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupToken", PldInfo->GroupToken);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupPosition", PldInfo->GroupPosition);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Bay", PldInfo->Bay);
/* Fourth 32-bit dword */
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Ejectable", PldInfo->Ejectable);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "OspmEjectRequired", PldInfo->OspmEjectRequired);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "CabinetNumber", PldInfo->CabinetNumber);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "CardCageNumber", PldInfo->CardCageNumber);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Reference", PldInfo->Reference);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Rotation", PldInfo->Rotation);
- AcpiOsPrintf (ACPI_PLD_OUTPUT08, "Order", PldInfo->Order);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Ejectable", PldInfo->Ejectable);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_EjectRequired", PldInfo->OspmEjectRequired);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_CabinetNumber", PldInfo->CabinetNumber);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_CardCageNumber", PldInfo->CardCageNumber);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Reference", PldInfo->Reference);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Rotation", PldInfo->Rotation);
+
+ if (ByteCount < ACPI_PLD_REV1_BUFFER_SIZE)
+ {
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08P, "PLD_Order", PldInfo->Order);
+ }
+ else
+ {
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Order", PldInfo->Order);
+ }
/* Fifth 32-bit dword */
if (ByteCount >= ACPI_PLD_REV1_BUFFER_SIZE)
{
- AcpiOsPrintf (ACPI_PLD_OUTPUT16,"VerticalOffset", PldInfo->VerticalOffset);
- AcpiOsPrintf (ACPI_PLD_OUTPUT16,"HorizontalOffset", PldInfo->HorizontalOffset);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_VerticalOffset", PldInfo->VerticalOffset);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16P, "PLD_HorizontalOffset", PldInfo->HorizontalOffset);
}
ACPI_FREE (PldInfo);
@@ -692,6 +814,7 @@ AcpiDmUnicode (
UINT16 *WordData;
UINT32 WordCount;
UINT32 i;
+ int OutputValue;
/* Extract the buffer info as a WORD buffer */
@@ -704,7 +827,23 @@ AcpiDmUnicode (
AcpiOsPrintf ("\"");
for (i = 0; i < (WordCount - 1); i++)
{
- AcpiOsPrintf ("%c", (int) WordData[i]);
+ OutputValue = (int) WordData[i];
+
+ /* Handle values that must be escaped */
+
+ if ((OutputValue == '\"') ||
+ (OutputValue == '\\'))
+ {
+ AcpiOsPrintf ("\\%c", OutputValue);
+ }
+ else if (!ACPI_IS_PRINT (OutputValue))
+ {
+ AcpiOsPrintf ("\\x%2.2X", OutputValue);
+ }
+ else
+ {
+ AcpiOsPrintf ("%c", OutputValue);
+ }
}
AcpiOsPrintf ("\")");
diff --git a/source/components/disassembler/dmcstyle.c b/source/components/disassembler/dmcstyle.c
new file mode 100644
index 0000000..4db1b96
--- /dev/null
+++ b/source/components/disassembler/dmcstyle.c
@@ -0,0 +1,773 @@
+/*******************************************************************************
+ *
+ * Module Name: dmcstyle - Support for C-style operator disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdisasm.h"
+#include "acdebug.h"
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmcstyle")
+
+
+/* Local prototypes */
+
+static char *
+AcpiDmGetCompoundSymbol (
+ UINT16 AslOpcode);
+
+static void
+AcpiDmPromoteTarget (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Target);
+
+static BOOLEAN
+AcpiDmIsValidTarget (
+ ACPI_PARSE_OBJECT *Op);
+
+static BOOLEAN
+AcpiDmIsTargetAnOperand (
+ ACPI_PARSE_OBJECT *Target,
+ ACPI_PARSE_OBJECT *Operand,
+ BOOLEAN TopLevel);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCheckForSymbolicOpcode
+ *
+ * PARAMETERS: Op - Current parse object
+ * Walk - Current parse tree walk info
+ *
+ * RETURN: TRUE if opcode can be converted to symbolic, FALSE otherwise
+ *
+ * DESCRIPTION: This is the main code that implements disassembly of AML code
+ * to C-style operators. Called during descending phase of the
+ * parse tree walk.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmCheckForSymbolicOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OP_WALK_INFO *Info)
+{
+ char *OperatorSymbol = NULL;
+ ACPI_PARSE_OBJECT *Child1;
+ ACPI_PARSE_OBJECT *Child2;
+ ACPI_PARSE_OBJECT *Target;
+
+
+ /* Exit immediately if ASL+ not enabled */
+
+ if (!AcpiGbl_CstyleDisassembly)
+ {
+ return (FALSE);
+ }
+
+ /* Get the first operand */
+
+ Child1 = AcpiPsGetArg (Op, 0);
+ if (!Child1)
+ {
+ return (FALSE);
+ }
+
+ /* Get the second operand */
+
+ Child2 = Child1->Common.Next;
+
+ /* Setup the operator string for this opcode */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ OperatorSymbol = " + ";
+ break;
+
+ case AML_SUBTRACT_OP:
+ OperatorSymbol = " - ";
+ break;
+
+ case AML_MULTIPLY_OP:
+ OperatorSymbol = " * ";
+ break;
+
+ case AML_DIVIDE_OP:
+ OperatorSymbol = " / ";
+ break;
+
+ case AML_MOD_OP:
+ OperatorSymbol = " % ";
+ break;
+
+ case AML_SHIFT_LEFT_OP:
+ OperatorSymbol = " << ";
+ break;
+
+ case AML_SHIFT_RIGHT_OP:
+ OperatorSymbol = " >> ";
+ break;
+
+ case AML_BIT_AND_OP:
+ OperatorSymbol = " & ";
+ break;
+
+ case AML_BIT_OR_OP:
+ OperatorSymbol = " | ";
+ break;
+
+ case AML_BIT_XOR_OP:
+ OperatorSymbol = " ^ ";
+ break;
+
+ /* Logical operators, no target */
+
+ case AML_LAND_OP:
+ OperatorSymbol = " && ";
+ break;
+
+ case AML_LEQUAL_OP:
+ OperatorSymbol = " == ";
+ break;
+
+ case AML_LGREATER_OP:
+ OperatorSymbol = " > ";
+ break;
+
+ case AML_LLESS_OP:
+ OperatorSymbol = " < ";
+ break;
+
+ case AML_LOR_OP:
+ OperatorSymbol = " || ";
+ break;
+
+ case AML_LNOT_OP:
+ /*
+ * Check for the LNOT sub-opcodes. These correspond to
+ * LNotEqual, LLessEqual, and LGreaterEqual. There are
+ * no actual AML opcodes for these operators.
+ */
+ switch (Child1->Common.AmlOpcode)
+ {
+ case AML_LEQUAL_OP:
+ OperatorSymbol = " != ";
+ break;
+
+ case AML_LGREATER_OP:
+ OperatorSymbol = " <= ";
+ break;
+
+ case AML_LLESS_OP:
+ OperatorSymbol = " >= ";
+ break;
+
+ default:
+
+ /* Unary LNOT case, emit "!" immediately */
+
+ AcpiOsPrintf ("!");
+ return (TRUE);
+ }
+
+ Child1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
+ Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
+
+ /* Save symbol string in the next child (not peer) */
+
+ Child2 = AcpiPsGetArg (Child1, 0);
+ if (!Child2)
+ {
+ return (FALSE);
+ }
+
+ Child2->Common.OperatorSymbol = OperatorSymbol;
+ return (TRUE);
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+ Child1->Common.OperatorSymbol = " [";
+ Child2->Common.OperatorSymbol = "]";
+ break;
+#endif
+
+ /* Unary operators */
+
+ case AML_DECREMENT_OP:
+ OperatorSymbol = "--";
+ break;
+
+ case AML_INCREMENT_OP:
+ OperatorSymbol = "++";
+ break;
+
+ case AML_BIT_NOT_OP:
+ case AML_STORE_OP:
+ OperatorSymbol = NULL;
+ break;
+
+ default:
+ return (FALSE);
+ }
+
+ if (Child1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)
+ {
+ return (TRUE);
+ }
+
+ /*
+ * This is the key to how the disassembly of the C-style operators
+ * works. We save the operator symbol in the first child, thus
+ * deferring symbol output until after the first operand has been
+ * emitted.
+ */
+ if (!Child1->Common.OperatorSymbol)
+ {
+ Child1->Common.OperatorSymbol = OperatorSymbol;
+ }
+
+ /*
+ * Check for a valid target as the 3rd (or sometimes 2nd) operand
+ *
+ * Compound assignment operator support:
+ * Attempt to optimize constructs of the form:
+ * Add (Local1, 0xFF, Local1)
+ * to:
+ * Local1 += 0xFF
+ *
+ * Only the math operators and Store() have a target.
+ * Logicals have no target.
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+
+ /* Target is 3rd operand */
+
+ Target = Child2->Common.Next;
+ if (Op->Common.AmlOpcode == AML_DIVIDE_OP)
+ {
+ /*
+ * Divide has an extra target operand (Remainder).
+ * If this extra target is specified, it cannot be converted
+ * to a C-style operator
+ */
+ if (AcpiDmIsValidTarget (Target))
+ {
+ Child1->Common.OperatorSymbol = NULL;
+ return (FALSE);
+ }
+
+ Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ Target = Target->Common.Next;
+ }
+
+ /* Parser should ensure there is at least a placeholder target */
+
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ if (!AcpiDmIsValidTarget (Target))
+ {
+ /* Not a valid target (placeholder only, from parser) */
+ break;
+ }
+
+ /*
+ * Promote the target up to the first child in the parse
+ * tree. This is done because the target will be output
+ * first, in the form:
+ * <Target> = Operands...
+ */
+ AcpiDmPromoteTarget (Op, Target);
+
+ /*
+ * Check for possible conversion to a "Compound Assignment".
+ *
+ * Determine if either operand is the same as the target
+ * and display compound assignment operator and other operand.
+ */
+ if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
+ (AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
+ {
+ Target->Common.OperatorSymbol =
+ AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
+
+ /* Convert operator to compound assignment */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
+ Child1->Common.OperatorSymbol = NULL;
+ return (TRUE);
+ }
+
+ /*
+ * If we are within a C-style expression, emit an extra open
+ * paren. Implemented by examining the parent op.
+ */
+ switch (Op->Common.Parent->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ case AML_LAND_OP:
+ case AML_LEQUAL_OP:
+ case AML_LGREATER_OP:
+ case AML_LLESS_OP:
+ case AML_LOR_OP:
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_ASSIGNMENT;
+ AcpiOsPrintf ("(");
+ break;
+
+ default:
+ break;
+ }
+
+ /* Normal output for ASL/AML operators with a target operand */
+
+ Target->Common.OperatorSymbol = " = (";
+ return (TRUE);
+
+ /* Binary operators, no parens */
+
+ case AML_DECREMENT_OP:
+ case AML_INCREMENT_OP:
+ return (TRUE);
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+
+ /* Target is optional, 3rd operand */
+
+ Target = Child2->Common.Next;
+ if (AcpiDmIsValidTarget (Target))
+ {
+ AcpiDmPromoteTarget (Op, Target);
+
+ if (!Target->Common.OperatorSymbol)
+ {
+ Target->Common.OperatorSymbol = " = ";
+ }
+ }
+ return (TRUE);
+#endif
+
+ case AML_STORE_OP:
+ /*
+ * Target is the 2nd operand.
+ * We know the target is valid, it is not optional.
+ * In the parse tree, simply swap the target with the
+ * source so that the target is processed first.
+ */
+ Target = Child1->Common.Next;
+ AcpiDmPromoteTarget (Op, Target);
+
+ if (!Target->Common.OperatorSymbol)
+ {
+ Target->Common.OperatorSymbol = " = ";
+ }
+ return (TRUE);
+
+ case AML_BIT_NOT_OP:
+
+ /* Target is optional, 2nd operand */
+
+ Target = Child1->Common.Next;
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ if (AcpiDmIsValidTarget (Target))
+ {
+ /* Valid target, not a placeholder */
+
+ AcpiDmPromoteTarget (Op, Target);
+ Target->Common.OperatorSymbol = " = ~";
+ }
+ else
+ {
+ /* No target. Emit this prefix operator immediately */
+
+ AcpiOsPrintf ("~");
+ }
+ return (TRUE);
+
+ default:
+ break;
+ }
+
+ /* All other operators, emit an open paren */
+
+ AcpiOsPrintf ("(");
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCloseOperator
+ *
+ * PARAMETERS: Op - Current parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Closes an operator by adding a closing parentheses if and
+ * when necessary. Called during ascending phase of the
+ * parse tree walk.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCloseOperator (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* Always emit paren if ASL+ disassembly disabled */
+
+ if (!AcpiGbl_CstyleDisassembly)
+ {
+ AcpiOsPrintf (")");
+ return;
+ }
+
+ /* Check if we need to add an additional closing paren */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ case AML_LAND_OP:
+ case AML_LEQUAL_OP:
+ case AML_LGREATER_OP:
+ case AML_LLESS_OP:
+ case AML_LOR_OP:
+
+ /* Emit paren only if this is not a compound assignment */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_COMPOUND)
+ {
+ return;
+ }
+
+ /* Emit extra close paren for assignment within an expression */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_ASSIGNMENT)
+ {
+ AcpiOsPrintf (")");
+ }
+ break;
+
+
+ /* No need for parens for these */
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+#endif
+ case AML_DECREMENT_OP:
+ case AML_INCREMENT_OP:
+ case AML_LNOT_OP:
+ case AML_BIT_NOT_OP:
+ case AML_STORE_OP:
+ return;
+
+ default:
+
+ /* Always emit paren for non-ASL+ operators */
+ break;
+ }
+
+ AcpiOsPrintf (")");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetCompoundSymbol
+ *
+ * PARAMETERS: AslOpcode
+ *
+ * RETURN: String containing the compound assignment symbol
+ *
+ * DESCRIPTION: Detect opcodes that can be converted to compound assignment,
+ * return the appropriate operator string.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiDmGetCompoundSymbol (
+ UINT16 AmlOpcode)
+{
+ char *Symbol;
+
+
+ switch (AmlOpcode)
+ {
+ case AML_ADD_OP:
+ Symbol = " += ";
+ break;
+
+ case AML_SUBTRACT_OP:
+ Symbol = " -= ";
+ break;
+
+ case AML_MULTIPLY_OP:
+ Symbol = " *= ";
+ break;
+
+ case AML_DIVIDE_OP:
+ Symbol = " /= ";
+ break;
+
+ case AML_MOD_OP:
+ Symbol = " %= ";
+ break;
+
+ case AML_SHIFT_LEFT_OP:
+ Symbol = " <<= ";
+ break;
+
+ case AML_SHIFT_RIGHT_OP:
+ Symbol = " >>= ";
+ break;
+
+ case AML_BIT_AND_OP:
+ Symbol = " &= ";
+ break;
+
+ case AML_BIT_OR_OP:
+ Symbol = " |= ";
+ break;
+
+ case AML_BIT_XOR_OP:
+ Symbol = " ^= ";
+ break;
+
+ default:
+
+ /* No operator string for all other opcodes */
+ return (NULL);
+ }
+
+ return (Symbol);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmPromoteTarget
+ *
+ * PARAMETERS: Op - Operator parse object
+ * Target - Target associate with the Op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Transform the parse tree by moving the target up to the first
+ * child of the Op.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmPromoteTarget (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Target)
+{
+ ACPI_PARSE_OBJECT *Child;
+
+
+ /* Link target directly to the Op as first child */
+
+ Child = Op->Common.Value.Arg;
+ Op->Common.Value.Arg = Target;
+ Target->Common.Next = Child;
+
+ /* Find the last peer, it is linked to the target. Unlink it. */
+
+ while (Child->Common.Next != Target)
+ {
+ Child = Child->Common.Next;
+ }
+
+ Child->Common.Next = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsValidTarget
+ *
+ * PARAMETERS: Target - Target Op from the parse tree
+ *
+ * RETURN: TRUE if the Target is real. FALSE if it is just a placeholder
+ * Op that was inserted by the parser.
+ *
+ * DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
+ * In other words, determine if the optional target is used or
+ * not.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiDmIsValidTarget (
+ ACPI_PARSE_OBJECT *Target)
+{
+
+ if ((Target->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ (Target->Common.Value.Arg == NULL))
+ {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsTargetAnOperand
+ *
+ * PARAMETERS: Target - Target associated with the expression
+ * Operand - An operand associated with expression
+ *
+ * RETURN: TRUE if expression can be converted to a compound assignment.
+ * FALSE otherwise.
+ *
+ * DESCRIPTION: Determine if the Target duplicates the operand, in order to
+ * detect if the expression can be converted to a compound
+ * assigment. (+=, *=, etc.)
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiDmIsTargetAnOperand (
+ ACPI_PARSE_OBJECT *Target,
+ ACPI_PARSE_OBJECT *Operand,
+ BOOLEAN TopLevel)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ BOOLEAN Same;
+
+
+ /*
+ * Opcodes must match. Note: ignoring the difference between nameseg
+ * and namepath for now. May be needed later.
+ */
+ if (Target->Common.AmlOpcode != Operand->Common.AmlOpcode)
+ {
+ return (FALSE);
+ }
+
+ /* Nodes should match, even if they are NULL */
+
+ if (Target->Common.Node != Operand->Common.Node)
+ {
+ return (FALSE);
+ }
+
+ /* Determine if a child exists */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Operand->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ Same = AcpiDmIsTargetAnOperand (Target->Common.Value.Arg,
+ Operand->Common.Value.Arg, FALSE);
+ if (!Same)
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Check the next peer, as long as we are not at the top level */
+
+ if ((!TopLevel) &&
+ Target->Common.Next)
+ {
+ Same = AcpiDmIsTargetAnOperand (Target->Common.Next,
+ Operand->Common.Next, FALSE);
+ if (!Same)
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Supress the duplicate operand at the top-level */
+
+ if (TopLevel)
+ {
+ Operand->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ }
+ return (TRUE);
+}
+
+#endif
diff --git a/source/components/disassembler/dmopcode.c b/source/components/disassembler/dmopcode.c
index e3d9e69..e356e38 100644
--- a/source/components/disassembler/dmopcode.c
+++ b/source/components/disassembler/dmopcode.c
@@ -54,6 +54,7 @@
#define _COMPONENT ACPI_CA_DEBUGGER
ACPI_MODULE_NAME ("dmopcode")
+
/* Local prototypes */
static void
@@ -567,7 +568,6 @@ AcpiDmRegionFlags (
ACPI_PARSE_OBJECT *Op)
{
-
/* The next Op contains the SpaceId */
Op = AcpiPsGetDepthNext (NULL, Op);
@@ -637,7 +637,6 @@ AcpiDmMatchKeyword (
ACPI_PARSE_OBJECT *Op)
{
-
if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
{
AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
@@ -694,27 +693,27 @@ AcpiDmDisassembleOneOp (
case ACPI_DASM_LNOT_SUFFIX:
- switch (Op->Common.AmlOpcode)
+ if (!AcpiGbl_CstyleDisassembly)
{
- case AML_LEQUAL_OP:
-
- AcpiOsPrintf ("LNotEqual");
- break;
-
- case AML_LGREATER_OP:
-
- AcpiOsPrintf ("LLessEqual");
- break;
-
- case AML_LLESS_OP:
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_LEQUAL_OP:
+ AcpiOsPrintf ("LNotEqual");
+ break;
- AcpiOsPrintf ("LGreaterEqual");
- break;
+ case AML_LGREATER_OP:
+ AcpiOsPrintf ("LLessEqual");
+ break;
- default:
+ case AML_LLESS_OP:
+ AcpiOsPrintf ("LGreaterEqual");
+ break;
- break;
+ default:
+ break;
+ }
}
+
Op->Common.DisasmOpcode = 0;
Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
return;
@@ -723,7 +722,6 @@ AcpiDmDisassembleOneOp (
break;
}
-
OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
/* The op and arguments */
@@ -845,7 +843,7 @@ AcpiDmDisassembleOneOp (
else if (AcpiDmIsPldBuffer (Op))
{
Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
- AcpiOsPrintf ("Buffer");
+ AcpiOsPrintf ("ToPLD (");
}
else
{
diff --git a/source/components/disassembler/dmutils.c b/source/components/disassembler/dmutils.c
index 700cfec..c075b69 100644
--- a/source/components/disassembler/dmutils.c
+++ b/source/components/disassembler/dmutils.c
@@ -256,6 +256,13 @@ AcpiDmCommaIfListMember (
if (AcpiDmListType (Op->Common.Parent) & BLOCK_COMMA_LIST)
{
+ /* Exit if Target has been marked IGNORE */
+
+ if (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
+ {
+ return (FALSE);
+ }
+
/* Check for a NULL target operand */
if ((Op->Common.Next->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
@@ -279,7 +286,13 @@ AcpiDmCommaIfListMember (
return (FALSE);
}
- AcpiOsPrintf (", ");
+ /* Emit comma only if this is not a C-style operator */
+
+ if (!Op->Common.OperatorSymbol)
+ {
+ AcpiOsPrintf (", ");
+ }
+
return (TRUE);
}
diff --git a/source/components/disassembler/dmwalk.c b/source/components/disassembler/dmwalk.c
index 92f27e5..823ce18 100644
--- a/source/components/disassembler/dmwalk.c
+++ b/source/components/disassembler/dmwalk.c
@@ -285,7 +285,8 @@ AcpiDmBlockType (
case AML_BUFFER_OP:
if ((Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) ||
- (Op->Common.DisasmOpcode == ACPI_DASM_UUID))
+ (Op->Common.DisasmOpcode == ACPI_DASM_UUID) ||
+ (Op->Common.DisasmOpcode == ACPI_DASM_PLD_METHOD))
{
return (BLOCK_NONE);
}
@@ -301,6 +302,17 @@ AcpiDmBlockType (
return (BLOCK_PAREN);
+ case AML_INT_METHODCALL_OP:
+
+ if (Op->Common.Parent &&
+ ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
+ {
+ /* This is a reference to a method, not an invocation */
+
+ return (BLOCK_NONE);
+ }
+
default:
OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
@@ -477,13 +489,20 @@ AcpiDmDescendingOp (
* keep track of the current column.
*/
Info->Count++;
- if (Info->Count /* +Info->LastLevel */ > 10)
+ if (Info->Count /* +Info->LastLevel */ > 12)
{
Info->Count = 0;
AcpiOsPrintf ("\n");
AcpiDmIndent (Info->LastLevel + 1);
}
+ /* If ASL+ is enabled, check for a C-style operator */
+
+ if (AcpiDmCheckForSymbolicOpcode (Op, Info))
+ {
+ return (AE_OK);
+ }
+
/* Print the opcode name */
AcpiDmDisassembleOneOp (NULL, Info, Op);
@@ -563,7 +582,6 @@ AcpiDmDescendingOp (
AcpiDmPredefinedDescription (Op);
break;
-
case AML_NAME_OP:
/* Check for _HID and related EISAID() */
@@ -572,13 +590,11 @@ AcpiDmDescendingOp (
AcpiOsPrintf (", ");
break;
-
case AML_REGION_OP:
AcpiDmRegionFlags (Op);
break;
-
case AML_POWER_RES_OP:
/* Mark the next two Ops as part of the parameter list */
@@ -591,7 +607,6 @@ AcpiDmDescendingOp (
NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
return (AE_OK);
-
case AML_PROCESSOR_OP:
/* Mark the next three Ops as part of the parameter list */
@@ -607,20 +622,17 @@ AcpiDmDescendingOp (
NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
return (AE_OK);
-
case AML_MUTEX_OP:
case AML_DATA_REGION_OP:
AcpiOsPrintf (", ");
return (AE_OK);
-
case AML_EVENT_OP:
case AML_ALIAS_OP:
return (AE_OK);
-
case AML_SCOPE_OP:
case AML_DEVICE_OP:
case AML_THERMAL_ZONE_OP:
@@ -628,7 +640,6 @@ AcpiDmDescendingOp (
AcpiOsPrintf (")");
break;
-
default:
AcpiOsPrintf ("*** Unhandled named opcode %X\n",
@@ -825,9 +836,9 @@ AcpiDmAscendingOp (
{
case BLOCK_PAREN:
- /* Completed an op that has arguments, add closing paren */
+ /* Completed an op that has arguments, add closing paren if needed */
- AcpiOsPrintf (")");
+ AcpiDmCloseOperator (Op);
if (Op->Common.AmlOpcode == AML_NAME_OP)
{
@@ -999,8 +1010,21 @@ AcpiDmAscendingOp (
{
Info->Level++;
}
+
+ /*
+ * For ASL+, check for and emit a C-style symbol. If valid, the
+ * symbol string has been deferred until after the first operand
+ */
+ if (AcpiGbl_CstyleDisassembly)
+ {
+ if (Op->Asl.OperatorSymbol)
+ {
+ AcpiOsPrintf ("%s", Op->Asl.OperatorSymbol);
+ Op->Asl.OperatorSymbol = NULL;
+ }
+ }
+
return (AE_OK);
}
-
#endif /* ACPI_DISASSEMBLER */
OpenPOWER on IntegriCloud