summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/acpica/disassembler/dmopcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel/io/acpica/disassembler/dmopcode.c')
-rw-r--r--usr/src/uts/intel/io/acpica/disassembler/dmopcode.c629
1 files changed, 573 insertions, 56 deletions
diff --git a/usr/src/uts/intel/io/acpica/disassembler/dmopcode.c b/usr/src/uts/intel/io/acpica/disassembler/dmopcode.c
index 6d2c3e1ecf..7ca171cbbb 100644
--- a/usr/src/uts/intel/io/acpica/disassembler/dmopcode.c
+++ b/usr/src/uts/intel/io/acpica/disassembler/dmopcode.c
@@ -5,7 +5,7 @@
******************************************************************************/
/*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2016, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,19 +45,395 @@
#include "accommon.h"
#include "acparser.h"
#include "amlcode.h"
-#include "acdisasm.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acdebug.h"
-#ifdef ACPI_DISASSEMBLER
#define _COMPONENT ACPI_CA_DEBUGGER
ACPI_MODULE_NAME ("dmopcode")
+
/* Local prototypes */
static void
AcpiDmMatchKeyword (
ACPI_PARSE_OBJECT *Op);
+static void
+AcpiDmConvertToElseIf (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisplayTargetPathname
+ *
+ * PARAMETERS: Op - Parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: For AML opcodes that have a target operand, display the full
+ * pathname for the target, in a comment field. Handles Return()
+ * statements also.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisplayTargetPathname (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_PARSE_OBJECT *PrevOp = NULL;
+ char *Pathname;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ if (Op->Common.AmlOpcode == AML_RETURN_OP)
+ {
+ PrevOp = Op->Asl.Value.Arg;
+ }
+ else
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_HAS_TARGET))
+ {
+ return;
+ }
+
+ /* Target is the last Op in the arg list */
+
+ NextOp = Op->Asl.Value.Arg;
+ while (NextOp)
+ {
+ PrevOp = NextOp;
+ NextOp = PrevOp->Asl.Next;
+ }
+ }
+
+ if (!PrevOp)
+ {
+ return;
+ }
+
+ /* We must have a namepath AML opcode */
+
+ if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
+ {
+ return;
+ }
+
+ /* A null string is the "no target specified" case */
+
+ if (!PrevOp->Asl.Value.String)
+ {
+ return;
+ }
+
+ /* No node means "unresolved external reference" */
+
+ if (!PrevOp->Asl.Node)
+ {
+ AcpiOsPrintf (" /* External reference */");
+ return;
+ }
+
+ /* Ignore if path is already from the root */
+
+ if (*PrevOp->Asl.Value.String == '\\')
+ {
+ return;
+ }
+
+ /* Now: we can get the full pathname */
+
+ Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node);
+ if (!Pathname)
+ {
+ return;
+ }
+
+ AcpiOsPrintf (" /* %s */", Pathname);
+ ACPI_FREE (Pathname);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmNotifyDescription
+ *
+ * PARAMETERS: Op - Name() parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a description comment for the value associated with a
+ * Notify() operator.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmNotifyDescription (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_NAMESPACE_NODE *Node;
+ UINT8 NotifyValue;
+ UINT8 Type = ACPI_TYPE_ANY;
+
+
+ /* The notify value is the second argument */
+
+ NextOp = Op->Asl.Value.Arg;
+ NextOp = NextOp->Asl.Next;
+
+ switch (NextOp->Common.AmlOpcode)
+ {
+ case AML_ZERO_OP:
+ case AML_ONE_OP:
+
+ NotifyValue = (UINT8) NextOp->Common.AmlOpcode;
+ break;
+
+ case AML_BYTE_OP:
+
+ NotifyValue = (UINT8) NextOp->Asl.Value.Integer;
+ break;
+
+ default:
+ return;
+ }
+
+ /*
+ * Attempt to get the namespace node so we can determine the object type.
+ * Some notify values are dependent on the object type (Device, Thermal,
+ * or Processor).
+ */
+ Node = Op->Asl.Node;
+ if (Node)
+ {
+ Type = Node->Type;
+ }
+
+ AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmPredefinedDescription
+ *
+ * PARAMETERS: Op - Name() parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a description comment for a predefined ACPI name.
+ * Used for iASL compiler only.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op)
+{
+#ifdef ACPI_ASL_COMPILER
+ const AH_PREDEFINED_NAME *Info;
+ char *NameString;
+ int LastCharIsDigit;
+ int LastCharsAreHex;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ /* Ensure that the comment field is emitted only once */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
+ {
+ return;
+ }
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
+
+ /* Predefined name must start with an underscore */
+
+ NameString = ACPI_CAST_PTR (char, &Op->Named.Name);
+ if (NameString[0] != '_')
+ {
+ return;
+ }
+
+ /*
+ * Check for the special ACPI names:
+ * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
+ * (where d=decimal_digit, x=hex_digit, a=anything)
+ *
+ * Convert these to the generic name for table lookup.
+ * Note: NameString is guaranteed to be upper case here.
+ */
+ LastCharIsDigit =
+ (isdigit ((int) NameString[3])); /* d */
+ LastCharsAreHex =
+ (isxdigit ((int) NameString[2]) && /* xx */
+ isxdigit ((int) NameString[3]));
+
+ switch (NameString[1])
+ {
+ case 'A':
+
+ if ((NameString[2] == 'C') && (LastCharIsDigit))
+ {
+ NameString = "_ACx";
+ }
+ else if ((NameString[2] == 'L') && (LastCharIsDigit))
+ {
+ NameString = "_ALx";
+ }
+ break;
+
+ case 'E':
+
+ if ((NameString[2] == 'J') && (LastCharIsDigit))
+ {
+ NameString = "_EJx";
+ }
+ else if (LastCharsAreHex)
+ {
+ NameString = "_Exx";
+ }
+ break;
+
+ case 'L':
+
+ if (LastCharsAreHex)
+ {
+ NameString = "_Lxx";
+ }
+ break;
+
+ case 'Q':
+
+ if (LastCharsAreHex)
+ {
+ NameString = "_Qxx";
+ }
+ break;
+
+ case 'T':
+
+ if (NameString[2] == '_')
+ {
+ NameString = "_T_x";
+ }
+ break;
+
+ case 'W':
+
+ if (LastCharsAreHex)
+ {
+ NameString = "_Wxx";
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ /* Match the name in the info table */
+
+ Info = AcpiAhMatchPredefinedName (NameString);
+ if (Info)
+ {
+ AcpiOsPrintf (" // %4.4s: %s",
+ NameString, ACPI_CAST_PTR (char, Info->Description));
+ }
+
+#endif
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFieldPredefinedDescription
+ *
+ * PARAMETERS: Op - Parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a description comment for a resource descriptor tag
+ * (which is a predefined ACPI name.) Used for iASL compiler only.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFieldPredefinedDescription (
+ ACPI_PARSE_OBJECT *Op)
+{
+#ifdef ACPI_ASL_COMPILER
+ ACPI_PARSE_OBJECT *IndexOp;
+ char *Tag;
+ const ACPI_OPCODE_INFO *OpInfo;
+ const AH_PREDEFINED_NAME *Info;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ /* Ensure that the comment field is emitted only once */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
+ {
+ return;
+ }
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
+
+ /*
+ * Op must be one of the Create* operators: CreateField, CreateBitField,
+ * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
+ */
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_CREATE))
+ {
+ return;
+ }
+
+ /* Second argument is the Index argument */
+
+ IndexOp = Op->Common.Value.Arg;
+ IndexOp = IndexOp->Common.Next;
+
+ /* Index argument must be a namepath */
+
+ if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
+ {
+ return;
+ }
+
+ /* Major cheat: We previously put the Tag ptr in the Node field */
+
+ Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
+ if (!Tag)
+ {
+ return;
+ }
+
+ /* Match the name in the info table */
+
+ Info = AcpiAhMatchPredefinedName (Tag);
+ if (Info)
+ {
+ AcpiOsPrintf (" // %4.4s: %s", Tag,
+ ACPI_CAST_PTR (char, Info->Description));
+ }
+
+#endif
+ return;
+}
+
/*******************************************************************************
*
@@ -195,7 +571,6 @@ AcpiDmRegionFlags (
ACPI_PARSE_OBJECT *Op)
{
-
/* The next Op contains the SpaceId */
Op = AcpiPsGetDepthNext (NULL, Op);
@@ -265,15 +640,14 @@ AcpiDmMatchKeyword (
ACPI_PARSE_OBJECT *Op)
{
-
if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
{
AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
}
else
{
- AcpiOsPrintf ("%s", ACPI_CAST_PTR (char,
- AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]));
+ AcpiOsPrintf ("%s",
+ AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);
}
}
@@ -304,6 +678,7 @@ AcpiDmDisassembleOneOp (
ACPI_PARSE_OBJECT *Child;
ACPI_STATUS Status;
UINT8 *Aml;
+ const AH_DEVICE_ID *IdInfo;
if (!Op)
@@ -312,6 +687,11 @@ AcpiDmDisassembleOneOp (
return;
}
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)
+ {
+ return; /* ElseIf macro was already emitted */
+ }
+
switch (Op->Common.DisasmOpcode)
{
case ACPI_DASM_MATCHOP:
@@ -320,23 +700,28 @@ AcpiDmDisassembleOneOp (
return;
case ACPI_DASM_LNOT_SUFFIX:
- switch (Op->Common.AmlOpcode)
+
+ if (!AcpiGbl_CstyleDisassembly)
{
- case AML_LEQUAL_OP:
- AcpiOsPrintf ("LNotEqual");
- break;
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_LEQUAL_OP:
+ AcpiOsPrintf ("LNotEqual");
+ break;
- case AML_LGREATER_OP:
- AcpiOsPrintf ("LLessEqual");
- break;
+ case AML_LGREATER_OP:
+ AcpiOsPrintf ("LLessEqual");
+ break;
- case AML_LLESS_OP:
- AcpiOsPrintf ("LGreaterEqual");
- break;
+ case AML_LLESS_OP:
+ AcpiOsPrintf ("LGreaterEqual");
+ break;
- default:
- break;
+ default:
+ break;
+ }
}
+
Op->Common.DisasmOpcode = 0;
Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
return;
@@ -345,7 +730,6 @@ AcpiDmDisassembleOneOp (
break;
}
-
OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
/* The op and arguments */
@@ -373,12 +757,11 @@ AcpiDmDisassembleOneOp (
AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
break;
-
case AML_WORD_OP:
if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
{
- AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
+ AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
}
else
{
@@ -386,12 +769,11 @@ AcpiDmDisassembleOneOp (
}
break;
-
case AML_DWORD_OP:
if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
{
- AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
+ AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
}
else
{
@@ -399,24 +781,33 @@ AcpiDmDisassembleOneOp (
}
break;
-
case AML_QWORD_OP:
AcpiOsPrintf ("0x%8.8X%8.8X",
ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
break;
-
case AML_STRING_OP:
- AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX);
- break;
+ AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
+ /* For _HID/_CID strings, attempt to output a descriptive comment */
- case AML_BUFFER_OP:
+ if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)
+ {
+ /* If we know about the ID, emit the description */
+ IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);
+ if (IdInfo)
+ {
+ AcpiOsPrintf (" /* %s */", IdInfo->Description);
+ }
+ }
+ break;
+
+ case AML_BUFFER_OP:
/*
- * Determine the type of buffer. We can have one of the following:
+ * Determine the type of buffer. We can have one of the following:
*
* 1) ResourceTemplate containing Resource Descriptors.
* 2) Unicode String buffer
@@ -429,7 +820,7 @@ AcpiDmDisassembleOneOp (
*/
if (!AcpiGbl_NoResourceDisassembly)
{
- Status = AcpiDmIsResourceTemplate (Op);
+ Status = AcpiDmIsResourceTemplate (WalkState, Op);
if (ACPI_SUCCESS (Status))
{
Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
@@ -438,11 +829,18 @@ AcpiDmDisassembleOneOp (
}
else if (Status == AE_AML_NO_RESOURCE_END_TAG)
{
- AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ ");
+ AcpiOsPrintf (
+ "/**** Is ResourceTemplate, "
+ "but EndTag not at buffer end ****/ ");
}
}
- if (AcpiDmIsUnicodeBuffer (Op))
+ if (AcpiDmIsUuidBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_UUID;
+ AcpiOsPrintf ("ToUUID (");
+ }
+ else if (AcpiDmIsUnicodeBuffer (Op))
{
Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
AcpiOsPrintf ("Unicode (");
@@ -452,33 +850,23 @@ AcpiDmDisassembleOneOp (
Op->Common.DisasmOpcode = ACPI_DASM_STRING;
AcpiOsPrintf ("Buffer");
}
- else
- {
- Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
- AcpiOsPrintf ("Buffer");
- }
- break;
-
-
- case AML_INT_STATICSTRING_OP:
-
- if (Op->Common.Value.String)
+ else if (AcpiDmIsPldBuffer (Op))
{
- AcpiOsPrintf ("%s", Op->Common.Value.String);
+ Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
+ AcpiOsPrintf ("ToPLD (");
}
else
{
- AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\"");
+ Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
+ AcpiOsPrintf ("Buffer");
}
break;
-
case AML_INT_NAMEPATH_OP:
AcpiDmNamestring (Op->Common.Value.Name);
break;
-
case AML_INT_NAMEDFIELD_OP:
Length = AcpiDmDumpName (Op->Named.Name);
@@ -489,7 +877,6 @@ AcpiDmDisassembleOneOp (
Info->BitOffset += (UINT32) Op->Common.Value.Integer;
break;
-
case AML_INT_RESERVEDFIELD_OP:
/* Offset() -- Must account for previous offsets */
@@ -509,7 +896,6 @@ AcpiDmDisassembleOneOp (
AcpiDmCommaIfFieldMember (Op);
break;
-
case AML_INT_ACCESSFIELD_OP:
case AML_INT_EXTACCESSFIELD_OP:
@@ -520,16 +906,15 @@ AcpiDmDisassembleOneOp (
if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
{
- AcpiOsPrintf (" (0x%2.2X)", (unsigned) ((Op->Common.Value.Integer >> 16) & 0xFF));
+ AcpiOsPrintf (" (0x%2.2X)", (unsigned)
+ ((Op->Common.Value.Integer >> 16) & 0xFF));
}
AcpiOsPrintf (")");
AcpiDmCommaIfFieldMember (Op);
break;
-
case AML_INT_CONNECTION_OP:
-
/*
* Two types of Connection() - one with a buffer object, the
* other with a namestring that points to a buffer object.
@@ -545,7 +930,9 @@ AcpiDmDisassembleOneOp (
Length = (UINT32) Child->Common.Value.Integer;
Info->Level += 1;
+ Info->MappingOp = Op;
Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
+
AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
Info->Level -= 1;
@@ -569,7 +956,6 @@ AcpiDmDisassembleOneOp (
AcpiDmByteList (Info, Op);
break;
-
case AML_INT_METHODCALL_OP:
Op = AcpiPsGetDepthNext (NULL, Op);
@@ -578,6 +964,23 @@ AcpiDmDisassembleOneOp (
AcpiDmNamestring (Op->Common.Value.Name);
break;
+ case AML_ELSE_OP:
+
+ AcpiDmConvertToElseIf (Op);
+ break;
+
+ case AML_EXTERNAL_OP:
+
+ if (AcpiGbl_DmEmitExternalOpcodes)
+ {
+ AcpiOsPrintf ("/* Opcode 0x15 */ ");
+
+ /* Fallthrough */
+ }
+ else
+ {
+ break;
+ }
default:
@@ -593,7 +996,7 @@ AcpiDmDisassembleOneOp (
(WalkState->Results) &&
(WalkState->ResultCount))
{
- AcpiDmDecodeInternalObject (
+ AcpiDbDecodeInternalObject (
WalkState->Results->Results.ObjDesc [
(WalkState->ResultCount - 1) %
ACPI_RESULTS_FRAME_OBJ_NUM]);
@@ -604,4 +1007,118 @@ AcpiDmDisassembleOneOp (
}
}
-#endif /* ACPI_DISASSEMBLER */
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmConvertToElseIf
+ *
+ * PARAMETERS: OriginalElseOp - ELSE Object to be examined
+ *
+ * RETURN: None. Emits either an "Else" or an "ElseIf" ASL operator.
+ *
+ * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf
+ *
+ * EXAMPLE:
+ *
+ * This If..Else..If nested sequence:
+ *
+ * If (Arg0 == 1)
+ * {
+ * Local0 = 4
+ * }
+ * Else
+ * {
+ * If (Arg0 == 2)
+ * {
+ * Local0 = 5
+ * }
+ * }
+ *
+ * Is converted to this simpler If..ElseIf sequence:
+ *
+ * If (Arg0 == 1)
+ * {
+ * Local0 = 4
+ * }
+ * ElseIf (Arg0 == 2)
+ * {
+ * Local0 = 5
+ * }
+ *
+ * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
+ * macro that emits an Else opcode followed by an If opcode. This function
+ * reverses these AML sequences back to an ElseIf macro where possible. This
+ * can make the disassembled ASL code simpler and more like the original code.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmConvertToElseIf (
+ ACPI_PARSE_OBJECT *OriginalElseOp)
+{
+ ACPI_PARSE_OBJECT *IfOp;
+ ACPI_PARSE_OBJECT *ElseOp;
+
+
+ /*
+ * To be able to perform the conversion, two conditions must be satisfied:
+ * 1) The first child of the Else must be an If statement.
+ * 2) The If block can only be followed by an Else block and these must
+ * be the only blocks under the original Else.
+ */
+ IfOp = OriginalElseOp->Common.Value.Arg;
+ if (!IfOp ||
+ (IfOp->Common.AmlOpcode != AML_IF_OP) ||
+ (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
+ {
+ /* Not an Else..If sequence, cannot convert to ElseIf */
+
+ AcpiOsPrintf ("%s", "Else");
+ return;
+ }
+
+ /* Emit ElseIf, mark the IF as now an ELSEIF */
+
+ AcpiOsPrintf ("%s", "ElseIf");
+ IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;
+
+ /* The IF parent will now be the same as the original ELSE parent */
+
+ IfOp->Common.Parent = OriginalElseOp->Common.Parent;
+
+ /*
+ * Update the NEXT pointers to restructure the parse tree, essentially
+ * promoting an If..Else block up to the same level as the original
+ * Else.
+ *
+ * Check if the IF has a corresponding ELSE peer
+ */
+ ElseOp = IfOp->Common.Next;
+ if (ElseOp &&
+ (ElseOp->Common.AmlOpcode == AML_ELSE_OP))
+ {
+ /* If an ELSE matches the IF, promote it also */
+
+ ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
+ ElseOp->Common.Next = OriginalElseOp->Common.Next;
+ }
+ else
+ {
+ /* Otherwise, set the IF NEXT to the original ELSE NEXT */
+
+ IfOp->Common.Next = OriginalElseOp->Common.Next;
+ }
+
+ /* Detach the child IF block from the original ELSE */
+
+ OriginalElseOp->Common.Value.Arg = NULL;
+
+ /* Ignore the original ELSE from now on */
+
+ OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
+
+ /* Insert IF (now ELSEIF) as next peer of the original ELSE */
+
+ OriginalElseOp->Common.Next = IfOp;
+}