summaryrefslogtreecommitdiff
path: root/usr/src/common/acpica/disassembler
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/common/acpica/disassembler')
-rw-r--r--usr/src/common/acpica/disassembler/acpica-resync.patch82
-rw-r--r--usr/src/common/acpica/disassembler/dmbuffer.c994
-rw-r--r--usr/src/common/acpica/disassembler/dmcstyle.c877
-rw-r--r--usr/src/common/acpica/disassembler/dmdeferred.c264
-rw-r--r--usr/src/common/acpica/disassembler/dmnames.c450
-rw-r--r--usr/src/common/acpica/disassembler/dmopcode.c1124
-rw-r--r--usr/src/common/acpica/disassembler/dmresrc.c448
-rw-r--r--usr/src/common/acpica/disassembler/dmresrcl.c1085
-rw-r--r--usr/src/common/acpica/disassembler/dmresrcl2.c750
-rw-r--r--usr/src/common/acpica/disassembler/dmresrcs.c369
-rw-r--r--usr/src/common/acpica/disassembler/dmutils.c330
-rw-r--r--usr/src/common/acpica/disassembler/dmwalk.c1100
12 files changed, 7873 insertions, 0 deletions
diff --git a/usr/src/common/acpica/disassembler/acpica-resync.patch b/usr/src/common/acpica/disassembler/acpica-resync.patch
new file mode 100644
index 0000000000..439905cee4
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/acpica-resync.patch
@@ -0,0 +1,82 @@
+This file and its contents are supplied under the terms of the
+Common Development and Distribution License ("CDDL"), version 1.0.
+You may only use this file in accordance with the terms of version
+1.0 of the CDDL.
+
+A full copy of the text of the CDDL should have accompanied this
+source. A copy of the CDDL is also available via the Internet at
+http://www.illumos.org/license/CDDL.
+
+Copyright (c) 2018, Joyent, Inc.
+
+---
+
+Files in this directory are used by kernel and user space code. Things that are
+unsupported in the kernel need to be excluded for kernel builds.
+
+
+diff --git a/usr/src/common/acpica/disassembler/dmbuffer.c b/usr/src/common/acpica/disassembler/dmbuffer.c
+index 79c37e2..923a485 100644
+--- a/usr/src/common/acpica/disassembler/dmbuffer.c
++++ b/usr/src/common/acpica/disassembler/dmbuffer.c
+@@ -375,6 +375,7 @@ AcpiDmUuid (
+ Data[8], Data[9],
+ Data[10], Data[11], Data[12], Data[13], Data[14], Data[15]);
+
++#ifdef ACPI_APPLICATION
+ /* Dump the UUID description string if available */
+
+ Description = AcpiAhMatchUuid (Data);
+@@ -382,6 +383,7 @@ AcpiDmUuid (
+ {
+ AcpiOsPrintf (" /* %s */", Description);
+ }
++#endif
+ }
+
+
+diff --git a/usr/src/common/acpica/disassembler/dmresrcl2.c b/usr/src/common/acpica/disassembler/dmresrcl2.c
+index c725bec..2e32731 100644
+--- a/usr/src/common/acpica/disassembler/dmresrcl2.c
++++ b/usr/src/common/acpica/disassembler/dmresrcl2.c
+@@ -250,8 +250,10 @@ AcpiDmGpioCommon (
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("}\n");
+
++#ifdef ACPI_APPLICATION
+ MpSaveGpioInfo (Info->MappingOp, Resource,
+ PinCount, PinList, DeviceName);
++#endif
+ }
+
+
+@@ -541,7 +543,9 @@ AcpiDmI2cSerialBusDescriptor (
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
++#ifdef ACPI_APPLICATION
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
++#endif
+ }
+
+
+@@ -624,7 +628,9 @@ AcpiDmSpiSerialBusDescriptor (
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
++#ifdef ACPI_APPLICATION
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
++#endif
+ }
+
+
+@@ -710,7 +716,9 @@ AcpiDmUartSerialBusDescriptor (
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
++#ifdef ACPI_APPLICATION
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
++#endif
+ }
+
+
diff --git a/usr/src/common/acpica/disassembler/dmbuffer.c b/usr/src/common/acpica/disassembler/dmbuffer.c
new file mode 100644
index 0000000000..923a4850d4
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmbuffer.c
@@ -0,0 +1,994 @@
+/*******************************************************************************
+ *
+ * Module Name: dmbuffer - AML disassembler, buffer and string support
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "acutils.h"
+#include "acdisasm.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acinterp.h"
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmbuffer")
+
+/* Local prototypes */
+
+static void
+AcpiDmUuid (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+AcpiDmUnicode (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+AcpiDmGetHardwareIdType (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+AcpiDmPldBuffer (
+ UINT32 Level,
+ UINT8 *ByteData,
+ UINT32 ByteCount);
+
+static const char *
+AcpiDmFindNameByIndex (
+ UINT64 Index,
+ const char **List);
+
+
+#define ACPI_BUFFER_BYTES_PER_LINE 8
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisasmByteList
+ *
+ * PARAMETERS: Level - Current source code indentation level
+ * ByteData - Pointer to the byte list
+ * ByteCount - Length of the byte list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump an AML "ByteList" in Hex format. 8 bytes per line, prefixed
+ * with the hex buffer offset.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisasmByteList (
+ UINT32 Level,
+ UINT8 *ByteData,
+ UINT32 ByteCount)
+{
+ UINT32 i;
+ UINT32 j;
+ UINT32 CurrentIndex;
+ UINT8 BufChar;
+
+
+ if (!ByteCount)
+ {
+ return;
+ }
+
+ for (i = 0; i < ByteCount; i += ACPI_BUFFER_BYTES_PER_LINE)
+ {
+ /* Line indent and offset prefix for each new line */
+
+ AcpiDmIndent (Level);
+ if (ByteCount > ACPI_BUFFER_BYTES_PER_LINE)
+ {
+ AcpiOsPrintf ("/* %04X */ ", i);
+ }
+
+ /* Dump the actual hex values */
+
+ for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)
+ {
+ CurrentIndex = i + j;
+ if (CurrentIndex >= ByteCount)
+ {
+ /* Dump fill spaces */
+
+ AcpiOsPrintf (" ");
+ continue;
+ }
+
+ AcpiOsPrintf (" 0x%2.2X", ByteData[CurrentIndex]);
+
+ /* Add comma if there are more bytes to display */
+
+ if (CurrentIndex < (ByteCount - 1))
+ {
+ AcpiOsPrintf (",");
+ }
+ else
+ {
+ AcpiOsPrintf (" ");
+ }
+ }
+
+ /* Dump the ASCII equivalents within a comment */
+
+ AcpiOsPrintf (" /* ");
+ for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++)
+ {
+ CurrentIndex = i + j;
+ if (CurrentIndex >= ByteCount)
+ {
+ break;
+ }
+
+ BufChar = ByteData[CurrentIndex];
+ if (isprint (BufChar))
+ {
+ AcpiOsPrintf ("%c", BufChar);
+ }
+ else
+ {
+ AcpiOsPrintf (".");
+ }
+ }
+
+ /* Finished with this line */
+
+ AcpiOsPrintf (" */\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmByteList
+ *
+ * PARAMETERS: Info - Parse tree walk info
+ * Op - Byte list op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a buffer byte list, handling the various types of buffers.
+ * Buffer type must be already set in the Op DisasmOpcode.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmByteList (
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+
+
+ ByteData = Op->Named.Data;
+ ByteCount = (UINT32) Op->Common.Value.Integer;
+
+ /*
+ * The byte list belongs to a buffer, and can be produced by either
+ * a ResourceTemplate, Unicode, quoted string, or a plain byte list.
+ */
+ switch (Op->Common.Parent->Common.DisasmOpcode)
+ {
+ case ACPI_DASM_RESOURCE:
+
+ AcpiDmResourceTemplate (
+ Info, Op->Common.Parent, ByteData, ByteCount);
+ break;
+
+ case ACPI_DASM_STRING:
+
+ AcpiDmIndent (Info->Level);
+ AcpiUtPrintString ((char *) ByteData, ACPI_UINT16_MAX);
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_DASM_UUID:
+
+ AcpiDmUuid (Op);
+ break;
+
+ case ACPI_DASM_UNICODE:
+
+ AcpiDmUnicode (Op);
+ break;
+
+ case ACPI_DASM_PLD_METHOD:
+#if 0
+ AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
+#endif
+ AcpiDmPldBuffer (Info->Level, ByteData, ByteCount);
+ break;
+
+ case ACPI_DASM_BUFFER:
+ default:
+ /*
+ * Not a resource, string, or unicode string.
+ * Just dump the buffer
+ */
+ AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsUuidBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a UUID
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a UUID
+ *
+ * To help determine whether the buffer is a UUID versus a raw data buffer,
+ * there a are a couple bytes we can look at:
+ *
+ * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
+ *
+ * The variant covered by the UUID specification is indicated by the two most
+ * significant bits of N being 1 0 (i.e., the hexadecimal N will always be
+ * 8, 9, A, or B).
+ *
+ * The variant covered by the UUID specification has five versions. For this
+ * variant, the four bits of M indicates the UUID version (i.e., the
+ * hexadecimal M will be either 1, 2, 3, 4, or 5).
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsUuidBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ /* Next, the initializer byte list to examine */
+
+ NextOp = SizeOp->Common.Next;
+ if (!NextOp)
+ {
+ return (FALSE);
+ }
+
+ /* Extract the byte list info */
+
+ ByteData = NextOp->Named.Data;
+ ByteCount = (UINT32) NextOp->Common.Value.Integer;
+
+ /* Byte count must be exactly 16 */
+
+ if (ByteCount != UUID_BUFFER_LENGTH)
+ {
+ return (FALSE);
+ }
+
+ /* Check for valid "M" and "N" values (see function header above) */
+
+ if (((ByteData[7] & 0xF0) == 0x00) || /* M={1,2,3,4,5} */
+ ((ByteData[7] & 0xF0) > 0x50) ||
+ ((ByteData[8] & 0xF0) < 0x80) || /* N={8,9,A,B} */
+ ((ByteData[8] & 0xF0) > 0xB0))
+ {
+ return (FALSE);
+ }
+
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUuid
+ *
+ * PARAMETERS: Op - Byte List op containing a UUID
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a buffer containing a UUID as a standard ASCII string.
+ *
+ * Output Format:
+ * In its canonical form, the UUID is represented by a string containing 32
+ * lowercase hexadecimal digits, displayed in 5 groups separated by hyphens.
+ * The complete form is 8-4-4-4-12 for a total of 36 characters (32
+ * alphanumeric characters representing hex digits and 4 hyphens). In bytes,
+ * 4-2-2-2-6. Example:
+ *
+ * ToUUID ("107ededd-d381-4fd7-8da9-08e9a6c79644")
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUuid (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *Data;
+ const char *Description;
+
+
+ Data = ACPI_CAST_PTR (UINT8, Op->Named.Data);
+
+ /* Emit the 36-byte UUID string in the proper format/order */
+
+ AcpiOsPrintf (
+ "\"%2.2x%2.2x%2.2x%2.2x-"
+ "%2.2x%2.2x-"
+ "%2.2x%2.2x-"
+ "%2.2x%2.2x-"
+ "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\")",
+ Data[3], Data[2], Data[1], Data[0],
+ Data[5], Data[4],
+ Data[7], Data[6],
+ Data[8], Data[9],
+ Data[10], Data[11], Data[12], Data[13], Data[14], Data[15]);
+
+#ifdef ACPI_APPLICATION
+ /* Dump the UUID description string if available */
+
+ Description = AcpiAhMatchUuid (Data);
+ if (Description)
+ {
+ AcpiOsPrintf (" /* %s */", Description);
+ }
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsUnicodeBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a UNICODE string
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a Unicode string
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsUnicodeBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+ UINT32 WordCount;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 i;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ /* Next, the initializer byte list to examine */
+
+ NextOp = SizeOp->Common.Next;
+ if (!NextOp)
+ {
+ return (FALSE);
+ }
+
+ /* Extract the byte list info */
+
+ ByteData = NextOp->Named.Data;
+ ByteCount = (UINT32) NextOp->Common.Value.Integer;
+ WordCount = ACPI_DIV_2 (ByteCount);
+
+ /*
+ * Unicode string must have an even number of bytes and last
+ * word must be zero
+ */
+ if ((!ByteCount) ||
+ (ByteCount < 4) ||
+ (ByteCount & 1) ||
+ ((UINT16 *) (void *) ByteData)[WordCount - 1] != 0)
+ {
+ return (FALSE);
+ }
+
+ /* For each word, 1st byte must be ascii (1-0x7F), 2nd byte must be zero */
+
+ for (i = 0; i < (ByteCount - 2); i += 2)
+ {
+ if ((ByteData[i] == 0) ||
+ (ByteData[i] > 0x7F) ||
+ (ByteData[(ACPI_SIZE) i + 1] != 0))
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsStringBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a ASCII string
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsStringBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 i;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ /* Next, the initializer byte list to examine */
+
+ NextOp = SizeOp->Common.Next;
+ if (!NextOp)
+ {
+ return (FALSE);
+ }
+
+ /* Extract the byte list info */
+
+ ByteData = NextOp->Named.Data;
+ ByteCount = (UINT32) NextOp->Common.Value.Integer;
+
+ /* Last byte must be the null terminator */
+
+ if ((!ByteCount) ||
+ (ByteCount < 2) ||
+ (ByteData[ByteCount-1] != 0))
+ {
+ return (FALSE);
+ }
+
+ for (i = 0; i < (ByteCount - 1); i++)
+ {
+ /* TBD: allow some escapes (non-ascii chars).
+ * they will be handled in the string output routine
+ */
+
+ if (!isprint (ByteData[i]))
+ {
+ return (FALSE);
+ }
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsPldBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a _PLD structure
+ *
+ ******************************************************************************/
+
+BOOLEAN
+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)
+ {
+ return (FALSE);
+ }
+
+ /* Check for form: Name(_PLD, Buffer() {}). Not legal, however */
+
+ if (ParentOp->Common.AmlOpcode == AML_NAME_OP)
+ {
+ Node = ParentOp->Common.Node;
+
+ 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);
+ }
+
+ return (FALSE);
+ }
+
+ /* Check for proper form: Name(_PLD, Package() {Buffer() {}}) */
+
+ if (ParentOp->Common.AmlOpcode == AML_PACKAGE_OP)
+ {
+ ParentOp = ParentOp->Common.Parent;
+ if (!ParentOp)
+ {
+ return (FALSE);
+ }
+
+ if (ParentOp->Common.AmlOpcode == AML_NAME_OP)
+ {
+ Node = ParentOp->Common.Node;
+
+ 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);
+ }
+ }
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * 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 const char *
+AcpiDmFindNameByIndex (
+ UINT64 Index,
+ const char **List)
+{
+ const char *NameString;
+ UINT32 i;
+
+
+ /* Bounds check */
+
+ NameString = List[0];
+ i = 0;
+
+ while (NameString)
+ {
+ i++;
+ NameString = List[i];
+ }
+
+ if (Index >= i)
+ {
+ /* TBD: Add error msg */
+
+ return ("");
+ }
+
+ return (List[Index]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmPldBuffer
+ *
+ * PARAMETERS: Level - Current source code indentation level
+ * ByteData - Pointer to the byte list
+ * ByteCount - Length of the byte list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump and format the contents of a _PLD buffer object
+ *
+ ******************************************************************************/
+
+#define ACPI_PLD_OUTPUT08 "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT08P "%*.s%-22s = 0x%X)\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT16 "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT16P "%*.s%-22s = 0x%X)\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUT24 "%*.s%-22s = 0x%X,\n", ACPI_MUL_4 (Level), " "
+#define ACPI_PLD_OUTPUTSTR "%*.s%-22s = \"%s\",\n", ACPI_MUL_4 (Level), " "
+
+static void
+AcpiDmPldBuffer (
+ UINT32 Level,
+ UINT8 *ByteData,
+ UINT32 ByteCount)
+{
+ ACPI_PLD_INFO *PldInfo;
+ ACPI_STATUS Status;
+
+
+ /* Check for valid byte count */
+
+ if (ByteCount < ACPI_PLD_REV1_BUFFER_SIZE)
+ {
+ return;
+ }
+
+ /* Convert _PLD buffer to local _PLD struct */
+
+ Status = AcpiDecodePldBuffer (ByteData, ByteCount, &PldInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("\n");
+
+ /* First 32-bit dword */
+
+ 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, "PLD_Width", PldInfo->Width);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Height", PldInfo->Height);
+
+ /* Third 32-bit dword */
+
+ 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, AcpiGbl_PldPanelList));
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_VerticalPosition",
+ AcpiDmFindNameByIndex(PldInfo->VerticalPosition, AcpiGbl_PldVerticalPositionList));
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_HorizontalPosition",
+ AcpiDmFindNameByIndex(PldInfo->HorizontalPosition, AcpiGbl_PldHorizontalPositionList));
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Shape",
+ AcpiDmFindNameByIndex(PldInfo->Shape, AcpiGbl_PldShapeList));
+ 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, "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_REV2_BUFFER_SIZE)
+ {
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Order", PldInfo->Order);
+
+ /* Fifth 32-bit dword */
+
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_VerticalOffset", PldInfo->VerticalOffset);
+ AcpiOsPrintf (ACPI_PLD_OUTPUT16P, "PLD_HorizontalOffset", PldInfo->HorizontalOffset);
+ }
+ else /* Rev 1 buffer */
+ {
+ AcpiOsPrintf (ACPI_PLD_OUTPUT08P, "PLD_Order", PldInfo->Order);
+ }
+
+ ACPI_FREE (PldInfo);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUnicode
+ *
+ * PARAMETERS: Op - Byte List op containing Unicode string
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump Unicode string as a standard ASCII string. (Remove
+ * the extra zero bytes).
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUnicode (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT16 *WordData;
+ UINT32 WordCount;
+ UINT32 i;
+ int OutputValue;
+
+
+ /* Extract the buffer info as a WORD buffer */
+
+ WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data);
+ WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer));
+
+ /* Write every other byte as an ASCII character */
+
+ AcpiOsPrintf ("\"");
+ for (i = 0; i < (WordCount - 1); i++)
+ {
+ OutputValue = (int) WordData[i];
+
+ /* Handle values that must be escaped */
+
+ if ((OutputValue == '\"') ||
+ (OutputValue == '\\'))
+ {
+ AcpiOsPrintf ("\\%c", OutputValue);
+ }
+ else if (!isprint (OutputValue))
+ {
+ AcpiOsPrintf ("\\x%2.2X", OutputValue);
+ }
+ else
+ {
+ AcpiOsPrintf ("%c", OutputValue);
+ }
+ }
+
+ AcpiOsPrintf ("\")");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetHardwareIdType
+ *
+ * PARAMETERS: Op - Op to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Determine the type of the argument to a _HID or _CID
+ * 1) Strings are allowed
+ * 2) If Integer, determine if it is a valid EISAID
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGetHardwareIdType (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 BigEndianId;
+ UINT32 Prefix[3];
+ UINT32 i;
+
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_STRING_OP:
+
+ /* Mark this string as an _HID/_CID string */
+
+ Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING;
+ break;
+
+ case AML_WORD_OP:
+ case AML_DWORD_OP:
+
+ /* Determine if a Word/Dword is a valid encoded EISAID */
+
+ /* Swap from little-endian to big-endian to simplify conversion */
+
+ BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer);
+
+ /* Create the 3 leading ASCII letters */
+
+ Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40;
+ Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40;
+ Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40;
+
+ /* Verify that all 3 are ascii and alpha */
+
+ for (i = 0; i < 3; i++)
+ {
+ if (!ACPI_IS_ASCII (Prefix[i]) ||
+ !isalpha (Prefix[i]))
+ {
+ return;
+ }
+ }
+
+ /* Mark this node as convertable to an EISA ID string */
+
+ Op->Common.DisasmOpcode = ACPI_DASM_EISAID;
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCheckForHardwareId
+ *
+ * PARAMETERS: Op - Op to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Determine if a Name() Op is a _HID/_CID.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCheckForHardwareId (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Name;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ /* Get the NameSegment */
+
+ Name = AcpiPsGetName (Op);
+ if (!Name)
+ {
+ return;
+ }
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (!NextOp)
+ {
+ return;
+ }
+
+ /* Check for _HID - has one argument */
+
+ if (ACPI_COMPARE_NAME (&Name, METHOD_NAME__HID))
+ {
+ AcpiDmGetHardwareIdType (NextOp);
+ return;
+ }
+
+ /* Exit if not _CID */
+
+ if (!ACPI_COMPARE_NAME (&Name, METHOD_NAME__CID))
+ {
+ return;
+ }
+
+ /* _CID can contain a single argument or a package */
+
+ if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP)
+ {
+ AcpiDmGetHardwareIdType (NextOp);
+ return;
+ }
+
+ /* _CID with Package: get the package length, check all elements */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+ if (!NextOp)
+ {
+ return;
+ }
+
+ /* Don't need to use the length, just walk the peer list */
+
+ NextOp = NextOp->Common.Next;
+ while (NextOp)
+ {
+ AcpiDmGetHardwareIdType (NextOp);
+ NextOp = NextOp->Common.Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDecompressEisaId
+ *
+ * PARAMETERS: EncodedId - Raw encoded EISA ID.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String
+ * and emit the correct ASL statement. If the ID is known, emit
+ * a description of the ID as a comment.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDecompressEisaId (
+ UINT32 EncodedId)
+{
+ char IdBuffer[ACPI_EISAID_STRING_SIZE];
+ const AH_DEVICE_ID *Info;
+
+
+ /* Convert EISAID to a string an emit the statement */
+
+ AcpiExEisaIdToString (IdBuffer, EncodedId);
+ AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer);
+
+ /* If we know about the ID, emit the description */
+
+ Info = AcpiAhMatchHardwareId (IdBuffer);
+ if (Info)
+ {
+ AcpiOsPrintf (" /* %s */", Info->Description);
+ }
+}
diff --git a/usr/src/common/acpica/disassembler/dmcstyle.c b/usr/src/common/acpica/disassembler/dmcstyle.c
new file mode 100644
index 0000000000..2f61dea208
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmcstyle.c
@@ -0,0 +1,877 @@
+/*******************************************************************************
+ *
+ * Module Name: dmcstyle - Support for C-style operator disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "acdebug.h"
+
+
+#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;
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND_ASSIGNMENT;
+
+ /* Save symbol string in the next child (not peer) */
+
+ Child2 = AcpiPsGetArg (Child1, 0);
+ if (!Child2)
+ {
+ return (FALSE);
+ }
+
+ Child2->Common.OperatorSymbol = OperatorSymbol;
+ return (TRUE);
+
+ case AML_INDEX_OP:
+ /*
+ * Check for constant source operand. Note: although technically
+ * legal syntax, the iASL compiler does not support this with
+ * the symbolic operators for Index(). It doesn't make sense to
+ * use Index() with a constant anyway.
+ */
+ if ((Child1->Common.AmlOpcode == AML_STRING_OP) ||
+ (Child1->Common.AmlOpcode == AML_BUFFER_OP) ||
+ (Child1->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Child1->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_CLOSING_PAREN;
+ return (FALSE);
+ }
+
+ /* Index operator is [] */
+
+ Child1->Common.OperatorSymbol = " [";
+ Child2->Common.OperatorSymbol = "]";
+ break;
+
+ /* 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 operands for conversion to a "Compound Assignment" */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ /* Commutative operators */
+
+ case AML_ADD_OP:
+ case AML_MULTIPLY_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ /*
+ * For the commutative operators, we can convert to a
+ * compound statement only if at least one (either) operand
+ * is the same as the target.
+ *
+ * Add (A, B, A) --> A += B
+ * Add (B, A, A) --> A += B
+ * Add (B, C, A) --> A = (B + C)
+ */
+ 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_ASSIGNMENT;
+ Child1->Common.OperatorSymbol = NULL;
+ return (TRUE);
+ }
+ break;
+
+ /* Non-commutative operators */
+
+ case AML_SUBTRACT_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ /*
+ * For the non-commutative operators, we can convert to a
+ * compound statement only if the target is the same as the
+ * first operand.
+ *
+ * Subtract (A, B, A) --> A -= B
+ * Subtract (B, A, A) --> A = (B - A)
+ */
+ if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)))
+ {
+ Target->Common.OperatorSymbol =
+ AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
+
+ /* Convert operator to compound assignment */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND_ASSIGNMENT;
+ Child1->Common.OperatorSymbol = NULL;
+ return (TRUE);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * 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);
+
+ 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);
+
+ 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;
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ 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;
+ }
+
+ /*
+ * Nodes marked with ACPI_PARSEOP_PARAMLIST don't need a parens
+ * output here. We also need to check the parent to see if this op
+ * is part of a compound test (!=, >=, <=).
+ */
+ if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) ||
+ ((Op->Common.Parent->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) &&
+ (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)))
+ {
+ /* Do Nothing. Paren already generated */
+ return (TRUE);
+ }
+
+ /* 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)
+{
+ BOOLEAN IsCStyleOp = FALSE;
+
+ /* 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_ASSIGNMENT)
+ {
+ return;
+ }
+
+ /* Emit extra close paren for assignment within an expression */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_ASSIGNMENT)
+ {
+ AcpiOsPrintf (")");
+ }
+
+ IsCStyleOp = TRUE;
+ break;
+
+ case AML_INDEX_OP:
+
+ /* This is case for unsupported Index() source constants */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_CLOSING_PAREN)
+ {
+ AcpiOsPrintf (")");
+ }
+ return;
+
+ /* No need for parens for these */
+
+ 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;
+ }
+
+ /*
+ * Nodes marked with ACPI_PARSEOP_PARAMLIST don't need a parens
+ * output here. We also need to check the parent to see if this op
+ * is part of a compound test (!=, >=, <=).
+ */
+ if (IsCStyleOp &&
+ ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) ||
+ ((Op->Common.Parent->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) &&
+ (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX))))
+ {
+ return;
+ }
+
+ AcpiOsPrintf (")");
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * 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. Note: If Target is NULL, something is seriously wrong,
+ * probably with the parse tree.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiDmIsValidTarget (
+ ACPI_PARSE_OBJECT *Target)
+{
+
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ 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);
+}
diff --git a/usr/src/common/acpica/disassembler/dmdeferred.c b/usr/src/common/acpica/disassembler/dmdeferred.c
new file mode 100644
index 0000000000..387980b893
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmdeferred.c
@@ -0,0 +1,264 @@
+/******************************************************************************
+ *
+ * Module Name: dmdeferred - Disassembly of deferred AML opcodes
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "acdispat.h"
+#include "amlcode.h"
+#include "acdisasm.h"
+#include "acparser.h"
+
+#define _COMPONENT ACPI_CA_DISASSEMBLER
+ ACPI_MODULE_NAME ("dmdeferred")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDmDeferredParse (
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *Aml,
+ UINT32 AmlLength);
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiDmParseDeferredOps
+ *
+ * PARAMETERS: Root - Root of the parse tree
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.)
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiDmParseDeferredOps (
+ ACPI_PARSE_OBJECT *Root)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_PARSE_OBJECT *Op = Root;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Traverse the entire parse tree */
+
+ while (Op)
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_DEFER))
+ {
+ Op = AcpiPsGetDepthNext (Root, Op);
+ continue;
+ }
+
+ /* Now we know we have a deferred opcode */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_METHOD_OP:
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ Status = AcpiDmDeferredParse (
+ Op, Op->Named.Data, Op->Named.Length);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ /* We don't need to do anything for these deferred opcodes */
+
+ case AML_REGION_OP:
+ case AML_DATA_REGION_OP:
+ case AML_CREATE_QWORD_FIELD_OP:
+ case AML_CREATE_DWORD_FIELD_OP:
+ case AML_CREATE_WORD_FIELD_OP:
+ case AML_CREATE_BYTE_FIELD_OP:
+ case AML_CREATE_BIT_FIELD_OP:
+ case AML_CREATE_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unhandled deferred AML opcode [0x%.4X]",
+ Op->Common.AmlOpcode));
+ break;
+ }
+
+ Op = AcpiPsGetDepthNext (Root, Op);
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiDmDeferredParse
+ *
+ * PARAMETERS: Op - Root Op of the deferred opcode
+ * Aml - Pointer to the raw AML
+ * AmlLength - Length of the AML
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse one deferred opcode
+ * (Methods, operation regions, etc.)
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiDmDeferredParse (
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *Aml,
+ UINT32 AmlLength)
+{
+ ACPI_WALK_STATE *WalkState;
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *SearchOp;
+ ACPI_PARSE_OBJECT *StartOp;
+ ACPI_PARSE_OBJECT *NewRootOp;
+ ACPI_PARSE_OBJECT *ExtraOp;
+
+
+ ACPI_FUNCTION_TRACE (DmDeferredParse);
+
+
+ if (!Aml || !AmlLength)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing deferred opcode %s [%4.4s]\n",
+ Op->Common.AmlOpName, (char *) &Op->Named.Name));
+
+ /* Need a new walk state to parse the AML */
+
+ WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
+ if (!WalkState)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml,
+ AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Parse the AML for this deferred opcode */
+
+ WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
+ WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
+ Status = AcpiPsParseAml (WalkState);
+
+ StartOp = (Op->Common.Value.Arg)->Common.Next;
+ SearchOp = StartOp;
+ while (SearchOp)
+ {
+ SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
+ }
+
+ /*
+ * For Buffer and Package opcodes, link the newly parsed subtree
+ * into the main parse tree
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_PACKAGE_OP:
+
+ ExtraOp = Op->Common.Value.Arg;
+ NewRootOp = ExtraOp->Common.Next;
+ ACPI_FREE (ExtraOp);
+ break;
+
+ case AML_VAR_PACKAGE_OP:
+ case AML_BUFFER_OP:
+ default:
+
+ NewRootOp = Op->Common.Value.Arg;
+ break;
+ }
+
+ Op->Common.Value.Arg = NewRootOp->Common.Value.Arg;
+
+ /* Must point all parents to the main tree */
+
+ StartOp = Op;
+ SearchOp = StartOp;
+ while (SearchOp)
+ {
+ if (SearchOp->Common.Parent == NewRootOp)
+ {
+ SearchOp->Common.Parent = Op;
+ }
+
+ SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
+ }
+
+ ACPI_FREE (NewRootOp);
+ break;
+
+ default:
+
+ break;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/usr/src/common/acpica/disassembler/dmnames.c b/usr/src/common/acpica/disassembler/dmnames.c
new file mode 100644
index 0000000000..89cfb2e985
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmnames.c
@@ -0,0 +1,450 @@
+/*******************************************************************************
+ *
+ * Module Name: dmnames - AML disassembler, names, namestrings, pathnames
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "amlcode.h"
+#include "acnamesp.h"
+#include "acdisasm.h"
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmnames")
+
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+AcpiDmDisplayPath (
+ ACPI_PARSE_OBJECT *Op);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpName
+ *
+ * PARAMETERS: Name - 4 character ACPI name
+ *
+ * RETURN: Final length of name
+ *
+ * DESCRIPTION: Dump an ACPI name, minus any trailing underscores.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmDumpName (
+ UINT32 Name)
+{
+ UINT32 i;
+ UINT32 Length;
+ char NewName[4];
+
+
+ /* Copy name locally in case the original name is not writeable */
+
+ *ACPI_CAST_PTR (UINT32, &NewName[0]) = Name;
+
+ /* Ensure that the name is printable, even if we have to fix it */
+
+ AcpiUtRepairName (NewName);
+
+ /* Remove all trailing underscores from the name */
+
+ Length = ACPI_NAME_SIZE;
+ for (i = (ACPI_NAME_SIZE - 1); i != 0; i--)
+ {
+ if (NewName[i] == '_')
+ {
+ Length--;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Dump the name, up to the start of the trailing underscores */
+
+ for (i = 0; i < Length; i++)
+ {
+ AcpiOsPrintf ("%c", NewName[i]);
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsDisplayObjectPathname
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Object whose pathname is to be obtained
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Diplay the pathname associated with a named object. Two
+ * versions. One searches the parse tree (for parser-only
+ * applications suchas AcpiDump), and the other searches the
+ * ACPI namespace (the parse tree is probably deleted)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsDisplayObjectPathname (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_BUFFER Buffer;
+ UINT32 DebugLevel;
+
+
+ /* Save current debug level so we don't get extraneous debug output */
+
+ DebugLevel = AcpiDbgLevel;
+ AcpiDbgLevel = 0;
+
+ /* Just get the Node out of the Op object */
+
+ Node = Op->Common.Node;
+ if (!Node)
+ {
+ /* Node not defined in this scope, look it up */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ WalkState, &(Node));
+
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * We can't get the pathname since the object is not in the
+ * namespace. This can happen during single stepping
+ * where a dynamic named object is *about* to be created.
+ */
+ AcpiOsPrintf (" [Path not found]");
+ goto Exit;
+ }
+
+ /* Save it for next time. */
+
+ Op->Common.Node = Node;
+ }
+
+ /* Convert NamedDesc/handle to a full pathname */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (Node, &Buffer, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("****Could not get pathname****)");
+ goto Exit;
+ }
+
+ AcpiOsPrintf (" (Path %s)", (char *) Buffer.Pointer);
+ ACPI_FREE (Buffer.Pointer);
+
+
+Exit:
+ /* Restore the debug level */
+
+ AcpiDbgLevel = DebugLevel;
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmNamestring
+ *
+ * PARAMETERS: Name - ACPI Name string to store
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode and dump an ACPI namestring. Handles prefix characters
+ *
+ ******************************************************************************/
+
+void
+AcpiDmNamestring (
+ char *Name)
+{
+ UINT32 SegCount;
+
+
+ if (!Name)
+ {
+ return;
+ }
+
+ /* Handle all Scope Prefix operators */
+
+ while (ACPI_IS_ROOT_PREFIX (ACPI_GET8 (Name)) ||
+ ACPI_IS_PARENT_PREFIX (ACPI_GET8 (Name)))
+ {
+ /* Append prefix character */
+
+ AcpiOsPrintf ("%1c", ACPI_GET8 (Name));
+ Name++;
+ }
+
+ switch (ACPI_GET8 (Name))
+ {
+ case 0:
+
+ SegCount = 0;
+ break;
+
+ case AML_DUAL_NAME_PREFIX:
+
+ SegCount = 2;
+ Name++;
+ break;
+
+ case AML_MULTI_NAME_PREFIX_OP:
+
+ SegCount = (UINT32) ACPI_GET8 (Name + 1);
+ Name += 2;
+ break;
+
+ default:
+
+ SegCount = 1;
+ break;
+ }
+
+ while (SegCount)
+ {
+ /* Append Name segment */
+
+ AcpiDmDumpName (*ACPI_CAST_PTR (UINT32, Name));
+
+ SegCount--;
+ if (SegCount)
+ {
+ /* Not last name, append dot separator */
+
+ AcpiOsPrintf (".");
+ }
+
+ Name += ACPI_NAME_SIZE;
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisplayPath
+ *
+ * PARAMETERS: Op - Named Op whose path is to be constructed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Walk backwards from current scope and display the name
+ * of each previous level of scope up to the root scope
+ * (like "pwd" does with file systems)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisplayPath (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Prev;
+ ACPI_PARSE_OBJECT *Search;
+ UINT32 Name;
+ BOOLEAN DoDot = FALSE;
+ ACPI_PARSE_OBJECT *NamePath;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ /* We are only interested in named objects */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_NSNODE))
+ {
+ return;
+ }
+
+ if (OpInfo->Flags & AML_CREATE)
+ {
+ /* Field creation - check for a fully qualified namepath */
+
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ NamePath = AcpiPsGetArg (Op, 3);
+ }
+ else
+ {
+ NamePath = AcpiPsGetArg (Op, 2);
+ }
+
+ if ((NamePath) &&
+ (NamePath->Common.Value.String) &&
+ (ACPI_IS_ROOT_PREFIX (NamePath->Common.Value.String[0])))
+ {
+ AcpiDmNamestring (NamePath->Common.Value.String);
+ return;
+ }
+ }
+
+ Prev = NULL; /* Start with Root Node */
+ while (Prev != Op)
+ {
+ /* Search upwards in the tree to find scope with "prev" as its parent */
+
+ Search = Op;
+ for (; ;)
+ {
+ if (Search->Common.Parent == Prev)
+ {
+ break;
+ }
+
+ /* Go up one level */
+
+ Search = Search->Common.Parent;
+ }
+
+ if (Prev)
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (Search->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_FIELD))
+ {
+ /* Below root scope, append scope name */
+
+ if (DoDot)
+ {
+ /* Append dot */
+
+ AcpiOsPrintf (".");
+ }
+
+ if (OpInfo->Flags & AML_CREATE)
+ {
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ NamePath = AcpiPsGetArg (Op, 3);
+ }
+ else
+ {
+ NamePath = AcpiPsGetArg (Op, 2);
+ }
+
+ if ((NamePath) &&
+ (NamePath->Common.Value.String))
+ {
+ AcpiDmDumpName (NamePath->Common.Value.String);
+ }
+ }
+ else
+ {
+ Name = AcpiPsGetName (Search);
+ AcpiDmDumpName ((char *) &Name);
+ }
+
+ DoDot = TRUE;
+ }
+ }
+
+ Prev = Search;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmValidateName
+ *
+ * PARAMETERS: Name - 4 character ACPI name
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Lookup the name
+ *
+ ******************************************************************************/
+
+void
+AcpiDmValidateName (
+ char *Name,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *TargetOp;
+
+
+ if ((!Name) ||
+ (!Op->Common.Parent))
+ {
+ return;
+ }
+
+ if (!Op->Common.Node)
+ {
+ AcpiOsPrintf (
+ " /**** Name not found or not accessible from this scope ****/ ");
+ }
+
+ if ((!Name) ||
+ (!Op->Common.Parent))
+ {
+ return;
+ }
+
+ TargetOp = AcpiPsFind (Op, Name, 0, 0);
+ if (!TargetOp)
+ {
+ /*
+ * Didn't find the name in the parse tree. This may be
+ * a problem, or it may simply be one of the predefined names
+ * (such as _OS_). Rather than worry about looking up all
+ * the predefined names, just display the name as given
+ */
+ AcpiOsPrintf (
+ " /**** Name not found or not accessible from this scope ****/ ");
+ }
+}
+#endif
diff --git a/usr/src/common/acpica/disassembler/dmopcode.c b/usr/src/common/acpica/disassembler/dmopcode.c
new file mode 100644
index 0000000000..7ca171cbbb
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmopcode.c
@@ -0,0 +1,1124 @@
+/*******************************************************************************
+ *
+ * Module Name: dmopcode - AML disassembler, specific AML opcodes
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "acinterp.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+
+
+#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;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMethodFlags
+ *
+ * PARAMETERS: Op - Method Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode control method flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMethodFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Flags;
+ UINT32 Args;
+
+
+ /* The next Op contains the flags */
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+ Flags = (UINT8) Op->Common.Value.Integer;
+ Args = Flags & 0x07;
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ /* 1) Method argument count */
+
+ AcpiOsPrintf (", %u, ", Args);
+
+ /* 2) Serialize rule */
+
+ if (!(Flags & 0x08))
+ {
+ AcpiOsPrintf ("Not");
+ }
+
+ AcpiOsPrintf ("Serialized");
+
+ /* 3) SyncLevel */
+
+ if (Flags & 0xF0)
+ {
+ AcpiOsPrintf (", %u", Flags >> 4);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFieldFlags
+ *
+ * PARAMETERS: Op - Field Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Field definition flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFieldFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Flags;
+
+
+ Op = Op->Common.Next;
+ Flags = (UINT8) Op->Common.Value.Integer;
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
+ AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
+ AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressSpace
+ *
+ * PARAMETERS: SpaceId - ID to be translated
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
+ *
+ ******************************************************************************/
+
+void
+AcpiDmAddressSpace (
+ UINT8 SpaceId)
+{
+
+ if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
+ {
+ if (SpaceId == 0x7F)
+ {
+ AcpiOsPrintf ("FFixedHW, ");
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%.2X, ", SpaceId);
+ }
+ }
+ else
+ {
+ AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmRegionFlags
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode OperationRegion flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmRegionFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* The next Op contains the SpaceId */
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ AcpiOsPrintf (", ");
+ AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMatchOp
+ *
+ * PARAMETERS: Op - Match Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Match opcode operands
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMatchOp (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp = NextOp->Common.Next;
+
+ if (!NextOp)
+ {
+ /* Handle partial tree during single-step */
+
+ return;
+ }
+
+ /* Mark the two nodes that contain the encoding for the match keywords */
+
+ NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
+
+ NextOp = NextOp->Common.Next;
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMatchKeyword
+ *
+ * PARAMETERS: Op - Match Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Match opcode operands
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMatchKeyword (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
+ {
+ AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
+ }
+ else
+ {
+ AcpiOsPrintf ("%s",
+ AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisassembleOneOp
+ *
+ * PARAMETERS: WalkState - Current walk info
+ * Info - Parse tree walk info
+ * Op - Op that is to be printed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Disassemble a single AML opcode
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisassembleOneOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo = NULL;
+ UINT32 Offset;
+ UINT32 Length;
+ ACPI_PARSE_OBJECT *Child;
+ ACPI_STATUS Status;
+ UINT8 *Aml;
+ const AH_DEVICE_ID *IdInfo;
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("<NULL OP PTR>");
+ return;
+ }
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)
+ {
+ return; /* ElseIf macro was already emitted */
+ }
+
+ switch (Op->Common.DisasmOpcode)
+ {
+ case ACPI_DASM_MATCHOP:
+
+ AcpiDmMatchKeyword (Op);
+ return;
+
+ case ACPI_DASM_LNOT_SUFFIX:
+
+ if (!AcpiGbl_CstyleDisassembly)
+ {
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_LEQUAL_OP:
+ AcpiOsPrintf ("LNotEqual");
+ break;
+
+ case AML_LGREATER_OP:
+ AcpiOsPrintf ("LLessEqual");
+ break;
+
+ case AML_LLESS_OP:
+ AcpiOsPrintf ("LGreaterEqual");
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ Op->Common.DisasmOpcode = 0;
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return;
+
+ default:
+ break;
+ }
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /* The op and arguments */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_LNOT_OP:
+
+ Child = Op->Common.Value.Arg;
+ if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) ||
+ (Child->Common.AmlOpcode == AML_LGREATER_OP) ||
+ (Child->Common.AmlOpcode == AML_LLESS_OP))
+ {
+ Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
+ Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
+ }
+ else
+ {
+ AcpiOsPrintf ("%s", OpInfo->Name);
+ }
+ break;
+
+ case AML_BYTE_OP:
+
+ AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
+ break;
+
+ case AML_WORD_OP:
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
+ {
+ AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
+ }
+ break;
+
+ case AML_DWORD_OP:
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
+ {
+ AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
+ }
+ 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_UINT16_MAX);
+
+ /* For _HID/_CID strings, attempt to output a descriptive comment */
+
+ 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:
+ *
+ * 1) ResourceTemplate containing Resource Descriptors.
+ * 2) Unicode String buffer
+ * 3) ASCII String buffer
+ * 4) Raw data buffer (if none of the above)
+ *
+ * Since there are no special AML opcodes to differentiate these
+ * types of buffers, we have to closely look at the data in the
+ * buffer to determine the type.
+ */
+ if (!AcpiGbl_NoResourceDisassembly)
+ {
+ Status = AcpiDmIsResourceTemplate (WalkState, Op);
+ if (ACPI_SUCCESS (Status))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
+ AcpiOsPrintf ("ResourceTemplate");
+ break;
+ }
+ else if (Status == AE_AML_NO_RESOURCE_END_TAG)
+ {
+ AcpiOsPrintf (
+ "/**** Is ResourceTemplate, "
+ "but EndTag not at buffer end ****/ ");
+ }
+ }
+
+ if (AcpiDmIsUuidBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_UUID;
+ AcpiOsPrintf ("ToUUID (");
+ }
+ else if (AcpiDmIsUnicodeBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
+ AcpiOsPrintf ("Unicode (");
+ }
+ else if (AcpiDmIsStringBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_STRING;
+ AcpiOsPrintf ("Buffer");
+ }
+ else if (AcpiDmIsPldBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
+ AcpiOsPrintf ("ToPLD (");
+ }
+ else
+ {
+ 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);
+ AcpiOsPrintf (",%*.s %u", (unsigned) (5 - Length), " ",
+ (UINT32) Op->Common.Value.Integer);
+ AcpiDmCommaIfFieldMember (Op);
+
+ Info->BitOffset += (UINT32) Op->Common.Value.Integer;
+ break;
+
+ case AML_INT_RESERVEDFIELD_OP:
+
+ /* Offset() -- Must account for previous offsets */
+
+ Offset = (UINT32) Op->Common.Value.Integer;
+ Info->BitOffset += Offset;
+
+ if (Info->BitOffset % 8 == 0)
+ {
+ AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
+ }
+ else
+ {
+ AcpiOsPrintf (" , %u", Offset);
+ }
+
+ AcpiDmCommaIfFieldMember (Op);
+ break;
+
+ case AML_INT_ACCESSFIELD_OP:
+ case AML_INT_EXTACCESSFIELD_OP:
+
+ AcpiOsPrintf ("AccessAs (%s, ",
+ AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
+
+ AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
+
+ if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
+ {
+ 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.
+ */
+ AcpiOsPrintf ("Connection (");
+ Child = Op->Common.Value.Arg;
+
+ if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
+ {
+ AcpiOsPrintf ("\n");
+
+ Aml = Child->Named.Data;
+ 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;
+ AcpiDmIndent (Info->Level);
+ }
+ else
+ {
+ AcpiDmNamestring (Child->Common.Value.Name);
+ }
+
+ AcpiOsPrintf (")");
+ AcpiDmCommaIfFieldMember (Op);
+ AcpiOsPrintf ("\n");
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
+ Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ break;
+
+ case AML_INT_BYTELIST_OP:
+
+ AcpiDmByteList (Info, Op);
+ break;
+
+ case AML_INT_METHODCALL_OP:
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ 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:
+
+ /* Just get the opcode name and print it */
+
+ AcpiOsPrintf ("%s", OpInfo->Name);
+
+
+#ifdef ACPI_DEBUGGER
+
+ if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
+ (WalkState) &&
+ (WalkState->Results) &&
+ (WalkState->ResultCount))
+ {
+ AcpiDbDecodeInternalObject (
+ WalkState->Results->Results.ObjDesc [
+ (WalkState->ResultCount - 1) %
+ ACPI_RESULTS_FRAME_OBJ_NUM]);
+ }
+#endif
+
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * 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;
+}
diff --git a/usr/src/common/acpica/disassembler/dmresrc.c b/usr/src/common/acpica/disassembler/dmresrc.c
new file mode 100644
index 0000000000..a486f1d892
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmresrc.c
@@ -0,0 +1,448 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrc.c - Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "amlcode.h"
+#include "acdisasm.h"
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrc")
+
+
+/* Dispatch tables for Resource disassembly functions */
+
+static ACPI_RESOURCE_HANDLER AcpiGbl_DmResourceDispatch [] =
+{
+ /* Small descriptors */
+
+ NULL, /* 0x00, Reserved */
+ NULL, /* 0x01, Reserved */
+ NULL, /* 0x02, Reserved */
+ NULL, /* 0x03, Reserved */
+ AcpiDmIrqDescriptor, /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
+ AcpiDmDmaDescriptor, /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
+ AcpiDmStartDependentDescriptor, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
+ AcpiDmEndDependentDescriptor, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
+ AcpiDmIoDescriptor, /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
+ AcpiDmFixedIoDescriptor, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
+ AcpiDmFixedDmaDescriptor, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
+ NULL, /* 0x0B, Reserved */
+ NULL, /* 0x0C, Reserved */
+ NULL, /* 0x0D, Reserved */
+ AcpiDmVendorSmallDescriptor, /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
+ NULL, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
+
+ /* Large descriptors */
+
+ NULL, /* 0x00, Reserved */
+ AcpiDmMemory24Descriptor, /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
+ AcpiDmGenericRegisterDescriptor,/* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
+ NULL, /* 0x03, Reserved */
+ AcpiDmVendorLargeDescriptor, /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
+ AcpiDmMemory32Descriptor, /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
+ AcpiDmFixedMemory32Descriptor, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
+ AcpiDmDwordDescriptor, /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
+ AcpiDmWordDescriptor, /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
+ AcpiDmInterruptDescriptor, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
+ AcpiDmQwordDescriptor, /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
+ AcpiDmExtendedDescriptor, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
+ AcpiDmGpioDescriptor, /* 0x0C, ACPI_RESOURCE_NAME_GPIO */
+ NULL, /* 0x0D, Reserved */
+ AcpiDmSerialBusDescriptor /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS */
+};
+
+
+/* Only used for single-threaded applications */
+/* TBD: remove when name is passed as parameter to the dump functions */
+
+static UINT32 ResourceName;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDescriptorName
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a name for the descriptor if one is present (indicated
+ * by the name being changed from the default name.) A name is only
+ * emitted if a reference to the descriptor has been made somewhere
+ * in the original ASL code.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDescriptorName (
+ void)
+{
+
+ if (ResourceName == ACPI_DEFAULT_RESNAME)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("%4.4s", (char *) &ResourceName);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpInteger*
+ *
+ * PARAMETERS: Value - Value to emit
+ * Name - Associated name (emitted as a comment)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Integer output helper functions
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpInteger8 (
+ UINT8 Value,
+ const char *Name)
+{
+ AcpiOsPrintf ("0x%2.2X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger16 (
+ UINT16 Value,
+ const char *Name)
+{
+ AcpiOsPrintf ("0x%4.4X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger32 (
+ UINT32 Value,
+ const char *Name)
+{
+ AcpiOsPrintf ("0x%8.8X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger64 (
+ UINT64 Value,
+ const char *Name)
+{
+ AcpiOsPrintf ("0x%8.8X%8.8X, // %s\n", ACPI_FORMAT_UINT64 (Value), Name);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmBitList
+ *
+ * PARAMETERS: Mask - 16-bit value corresponding to 16 interrupt
+ * or DMA values
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a bit mask as a list of individual interrupt/DMA levels.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmBitList (
+ UINT16 Mask)
+{
+ UINT32 i;
+ BOOLEAN Previous = FALSE;
+
+
+ /* Open the initializer list */
+
+ AcpiOsPrintf ("{");
+
+ /* Examine each bit */
+
+ for (i = 0; i < 16; i++)
+ {
+ /* Only interested in bits that are set to 1 */
+
+ if (Mask & 1)
+ {
+ if (Previous)
+ {
+ AcpiOsPrintf (",");
+ }
+
+ Previous = TRUE;
+ AcpiOsPrintf ("%u", i);
+ }
+
+ Mask >>= 1;
+ }
+
+ /* Close list */
+
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmResourceTemplate
+ *
+ * PARAMETERS: Info - Curent parse tree walk info
+ * ByteData - Pointer to the byte list data
+ * ByteCount - Length of the byte list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the contents of a Resource Template containing a set of
+ * Resource Descriptors.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmResourceTemplate (
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *ByteData,
+ UINT32 ByteCount)
+{
+ ACPI_STATUS Status;
+ UINT32 CurrentByteOffset;
+ UINT8 ResourceType;
+ UINT32 ResourceLength;
+ void *Aml;
+ UINT32 Level;
+ BOOLEAN DependentFns = FALSE;
+ UINT8 ResourceIndex;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ if (Op->Asl.AmlOpcode != AML_FIELD_OP)
+ {
+ Info->MappingOp = Op;
+ }
+
+ Level = Info->Level;
+ ResourceName = ACPI_DEFAULT_RESNAME;
+ Node = Op->Common.Node;
+ if (Node)
+ {
+ Node = Node->Child;
+ }
+
+ for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;)
+ {
+ Aml = &ByteData[CurrentByteOffset];
+
+ /* Get the descriptor type and length */
+
+ ResourceType = AcpiUtGetResourceType (Aml);
+ ResourceLength = AcpiUtGetResourceLength (Aml);
+
+ /* Validate the Resource Type and Resource Length */
+
+ Status = AcpiUtValidateResource (NULL, Aml, &ResourceIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf (
+ "/*** Could not validate Resource, type (%X) %s***/\n",
+ ResourceType, AcpiFormatException (Status));
+ return;
+ }
+
+ /* Point to next descriptor */
+
+ CurrentByteOffset += AcpiUtGetDescriptorLength (Aml);
+
+ /* Descriptor pre-processing */
+
+ switch (ResourceType)
+ {
+ case ACPI_RESOURCE_NAME_START_DEPENDENT:
+
+ /* Finish a previous StartDependentFns */
+
+ if (DependentFns)
+ {
+ Level--;
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+ }
+ break;
+
+ case ACPI_RESOURCE_NAME_END_DEPENDENT:
+
+ Level--;
+ DependentFns = FALSE;
+ break;
+
+ case ACPI_RESOURCE_NAME_END_TAG:
+
+ /* Normal exit, the resource list is finished */
+
+ if (DependentFns)
+ {
+ /*
+ * Close an open StartDependentDescriptor. This indicates a
+ * missing EndDependentDescriptor.
+ */
+ Level--;
+ DependentFns = FALSE;
+
+ /* Go ahead and insert EndDependentFn() */
+
+ AcpiDmEndDependentDescriptor (Info, Aml, ResourceLength, Level);
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf (
+ "/*** Disassembler: inserted "
+ "missing EndDependentFn () ***/\n");
+ }
+ return;
+
+ default:
+
+ break;
+ }
+
+ /* Disassemble the resource structure */
+
+ if (Node)
+ {
+ ResourceName = Node->Name.Integer;
+ Node = Node->Peer;
+ }
+
+ AcpiGbl_DmResourceDispatch [ResourceIndex] (
+ Info, Aml, ResourceLength, Level);
+
+ /* Descriptor post-processing */
+
+ if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT)
+ {
+ DependentFns = TRUE;
+ Level++;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsResourceTemplate
+ *
+ * PARAMETERS: WalkState - Current walk info
+ * Op - Buffer Op to be examined
+ *
+ * RETURN: Status. AE_OK if valid template
+ *
+ * DESCRIPTION: Walk a byte list to determine if it consists of a valid set
+ * of resource descriptors. Nothing is output.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDmIsResourceTemplate (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT8 *Aml;
+ UINT8 *EndAml;
+ ACPI_SIZE Length;
+
+
+ /* This op must be a buffer */
+
+ if (Op->Common.AmlOpcode != AML_BUFFER_OP)
+ {
+ return (AE_TYPE);
+ }
+
+ /* Get the ByteData list and length */
+
+ NextOp = Op->Common.Value.Arg;
+ if (!NextOp)
+ {
+ AcpiOsPrintf ("NULL byte list in buffer\n");
+ return (AE_TYPE);
+ }
+
+ NextOp = NextOp->Common.Next;
+ if (!NextOp)
+ {
+ return (AE_TYPE);
+ }
+
+ Aml = NextOp->Named.Data;
+ Length = (ACPI_SIZE) NextOp->Common.Value.Integer;
+
+ /* Walk the byte list, abort on any invalid descriptor type or length */
+
+ Status = AcpiUtWalkAmlResources (WalkState, Aml, Length,
+ NULL, ACPI_CAST_INDIRECT_PTR (void, &EndAml));
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_TYPE);
+ }
+
+ /*
+ * For the resource template to be valid, one EndTag must appear
+ * at the very end of the ByteList, not before. (For proper disassembly
+ * of a ResourceTemplate, the buffer must not have any extra data after
+ * the EndTag.)
+ */
+ if ((Aml + Length - sizeof (AML_RESOURCE_END_TAG)) != EndAml)
+ {
+ return (AE_AML_NO_RESOURCE_END_TAG);
+ }
+
+ /*
+ * All resource descriptors are valid, therefore this list appears
+ * to be a valid resource template
+ */
+ return (AE_OK);
+}
diff --git a/usr/src/common/acpica/disassembler/dmresrcl.c b/usr/src/common/acpica/disassembler/dmresrcl.c
new file mode 100644
index 0000000000..52fd3356b8
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmresrcl.c
@@ -0,0 +1,1085 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcl.c - "Large" Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "acdisasm.h"
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcl")
+
+
+/* Common names for address and memory descriptors */
+
+static const char *AcpiDmAddressNames[] =
+{
+ "Granularity",
+ "Range Minimum",
+ "Range Maximum",
+ "Translation Offset",
+ "Length"
+};
+
+static const char *AcpiDmMemoryNames[] =
+{
+ "Range Minimum",
+ "Range Maximum",
+ "Alignment",
+ "Length"
+};
+
+
+/* Local prototypes */
+
+static void
+AcpiDmSpaceFlags (
+ UINT8 Flags);
+
+static void
+AcpiDmIoFlags (
+ UINT8 Flags);
+
+static void
+AcpiDmIoFlags2 (
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmMemoryFlags (
+ UINT8 Flags,
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmMemoryFlags2 (
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmResourceSource (
+ AML_RESOURCE *Resource,
+ ACPI_SIZE MinimumLength,
+ UINT32 Length);
+
+static void
+AcpiDmAddressFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level);
+
+static void
+AcpiDmAddressPrefix (
+ UINT8 Type);
+
+static void
+AcpiDmAddressCommon (
+ AML_RESOURCE *Resource,
+ UINT8 Type,
+ UINT32 Level);
+
+static void
+AcpiDmAddressFlags (
+ AML_RESOURCE *Resource);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFields
+ *
+ * PARAMETERS: Source - Pointer to the contiguous data fields
+ * Type - 16 or 32 (bit)
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode fields common to Memory24 and Memory32 descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < 4; i++)
+ {
+ AcpiDmIndent (Level + 1);
+
+ switch (Type)
+ {
+ case 16:
+
+ AcpiDmDumpInteger16 (ACPI_CAST_PTR (UINT16, Source)[i],
+ AcpiDmMemoryNames[i]);
+ break;
+
+ case 32:
+
+ AcpiDmDumpInteger32 (ACPI_CAST_PTR (UINT32, Source)[i],
+ AcpiDmMemoryNames[i]);
+ break;
+
+ default:
+
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressFields
+ *
+ * PARAMETERS: Source - Pointer to the contiguous data fields
+ * Type - 16, 32, or 64 (bit)
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode fields common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ AcpiOsPrintf ("\n");
+
+ for (i = 0; i < 5; i++)
+ {
+ AcpiDmIndent (Level + 1);
+
+ switch (Type)
+ {
+ case 16:
+
+ AcpiDmDumpInteger16 (ACPI_CAST_PTR (UINT16, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ case 32:
+
+ AcpiDmDumpInteger32 (ACPI_CAST_PTR (UINT32, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ case 64:
+
+ AcpiDmDumpInteger64 (ACPI_CAST_PTR (UINT64, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ default:
+
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressPrefix
+ *
+ * PARAMETERS: Type - Descriptor type
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit name prefix representing the address descriptor type
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressPrefix (
+ UINT8 Type)
+{
+
+ switch (Type)
+ {
+ case ACPI_RESOURCE_TYPE_ADDRESS16:
+
+ AcpiOsPrintf ("Word");
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+
+ AcpiOsPrintf ("DWord");
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+
+ AcpiOsPrintf ("QWord");
+ break;
+
+ case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
+
+ AcpiOsPrintf ("Extended");
+ break;
+
+ default:
+
+ return;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressCommon
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ * Type - Descriptor type
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit common name and flag fields common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressCommon (
+ AML_RESOURCE *Resource,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT8 ResourceType;
+ UINT8 SpecificFlags;
+ UINT8 Flags;
+
+
+ ResourceType = Resource->Address.ResourceType;
+ SpecificFlags = Resource->Address.SpecificFlags;
+ Flags = Resource->Address.Flags;
+
+ AcpiDmIndent (Level);
+
+ /* Validate ResourceType */
+
+ if ((ResourceType > 2) && (ResourceType < 0xC0))
+ {
+ AcpiOsPrintf (
+ "/**** Invalid Resource Type: 0x%X ****/", ResourceType);
+ return;
+ }
+
+ /* Prefix is either Word, DWord, QWord, or Extended */
+
+ AcpiDmAddressPrefix (Type);
+
+ /* Resource Types above 0xC0 are vendor-defined */
+
+ if (ResourceType > 2)
+ {
+ AcpiOsPrintf ("Space (0x%2.2X, ", ResourceType);
+ AcpiDmSpaceFlags (Flags);
+ AcpiOsPrintf (" 0x%2.2X,", SpecificFlags);
+ return;
+ }
+
+ /* This is either a Memory, IO, or BusNumber descriptor (0,1,2) */
+
+ AcpiOsPrintf ("%s (",
+ AcpiGbl_WordDecode [ACPI_GET_2BIT_FLAG (ResourceType)]);
+
+ /* Decode the general and type-specific flags */
+
+ if (ResourceType == ACPI_MEMORY_RANGE)
+ {
+ AcpiDmMemoryFlags (Flags, SpecificFlags);
+ }
+ else /* IO range or BusNumberRange */
+ {
+ AcpiDmIoFlags (Flags);
+ if (ResourceType == ACPI_IO_RANGE)
+ {
+ AcpiOsPrintf (" %s,",
+ AcpiGbl_RngDecode [ACPI_GET_2BIT_FLAG (SpecificFlags)]);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressFlags
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit flags common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressFlags (
+ AML_RESOURCE *Resource)
+{
+
+ if (Resource->Address.ResourceType == ACPI_IO_RANGE)
+ {
+ AcpiDmIoFlags2 (Resource->Address.SpecificFlags);
+ }
+ else if (Resource->Address.ResourceType == ACPI_MEMORY_RANGE)
+ {
+ AcpiDmMemoryFlags2 (Resource->Address.SpecificFlags);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSpaceFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to Space Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmSpaceFlags (
+ UINT8 Flags)
+{
+
+ AcpiOsPrintf ("%s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Flags)],
+ AcpiGbl_DecDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 1)],
+ AcpiGbl_MinDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 2)],
+ AcpiGbl_MaxDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 3)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to IO Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmIoFlags (
+ UINT8 Flags)
+{
+ AcpiOsPrintf ("%s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Flags)],
+ AcpiGbl_MinDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 2)],
+ AcpiGbl_MaxDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 3)],
+ AcpiGbl_DecDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 1)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoFlags2
+ *
+ * PARAMETERS: SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to IO Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmIoFlags2 (
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf (", %s",
+ AcpiGbl_TtpDecode [ACPI_EXTRACT_1BIT_FLAG (SpecificFlags, 4)]);
+
+ /* TRS is only used if TTP is TypeTranslation */
+
+ if (SpecificFlags & 0x10)
+ {
+ AcpiOsPrintf (", %s",
+ AcpiGbl_TrsDecode [ACPI_EXTRACT_1BIT_FLAG (SpecificFlags, 5)]);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ * SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode flags specific to Memory Address Space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFlags (
+ UINT8 Flags,
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf ("%s, %s, %s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Flags)],
+ AcpiGbl_DecDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 1)],
+ AcpiGbl_MinDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 2)],
+ AcpiGbl_MaxDecode [ACPI_EXTRACT_1BIT_FLAG (Flags, 3)],
+ AcpiGbl_MemDecode [ACPI_EXTRACT_2BIT_FLAG (SpecificFlags, 1)],
+ AcpiGbl_RwDecode [ACPI_GET_1BIT_FLAG (SpecificFlags)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFlags2
+ *
+ * PARAMETERS: SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode flags specific to Memory Address Space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFlags2 (
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf (", %s, %s",
+ AcpiGbl_MtpDecode [ACPI_EXTRACT_2BIT_FLAG (SpecificFlags, 3)],
+ AcpiGbl_TtpDecode [ACPI_EXTRACT_1BIT_FLAG (SpecificFlags, 5)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmResourceSource
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ * MinimumLength - descriptor length without optional fields
+ * ResourceLength
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump optional ResourceSource fields of an address descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmResourceSource (
+ AML_RESOURCE *Resource,
+ ACPI_SIZE MinimumTotalLength,
+ UINT32 ResourceLength)
+{
+ UINT8 *AmlResourceSource;
+ UINT32 TotalLength;
+
+
+ TotalLength = ResourceLength + sizeof (AML_RESOURCE_LARGE_HEADER);
+
+ /* Check if the optional ResourceSource fields are present */
+
+ if (TotalLength <= MinimumTotalLength)
+ {
+ /* The two optional fields are not used */
+
+ AcpiOsPrintf (",, ");
+ return;
+ }
+
+ /* Get a pointer to the ResourceSource */
+
+ AmlResourceSource = ACPI_ADD_PTR (UINT8, Resource, MinimumTotalLength);
+
+ /*
+ * Always emit the ResourceSourceIndex (Byte)
+ *
+ * NOTE: Some ASL compilers always create a 0 byte (in the AML) for the
+ * Index even if the String does not exist. Although this is in violation
+ * of the ACPI specification, it is very important to emit ASL code that
+ * can be compiled back to the identical AML. There may be fields and/or
+ * indexes into the resource template buffer that are compiled to absolute
+ * offsets, and these will be broken if the AML length is changed.
+ */
+ AcpiOsPrintf ("0x%2.2X,", (UINT32) AmlResourceSource[0]);
+
+ /* Make sure that the ResourceSource string exists before dumping it */
+
+ if (TotalLength > (MinimumTotalLength + 1))
+ {
+ AcpiOsPrintf (" ");
+ AcpiUtPrintString ((char *) &AmlResourceSource[1], ACPI_UINT16_MAX);
+ }
+
+ AcpiOsPrintf (", ");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmWordDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Word Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmWordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS16, Level);
+
+ /* Dump the 5 contiguous WORD values */
+
+ AcpiDmAddressFields (&Resource->Address16.Granularity, 16, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS16), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDwordDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a DWord Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDwordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS32, Level);
+
+ /* Dump the 5 contiguous DWORD values */
+
+ AcpiDmAddressFields (&Resource->Address32.Granularity, 32, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS32), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmQwordDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a QWord Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmQwordDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS64, Level);
+
+ /* Dump the 5 contiguous QWORD values */
+
+ AcpiDmAddressFields (&Resource->Address64.Granularity, 64, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS64), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmExtendedDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Extended Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmExtendedDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (
+ Resource, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, Level);
+
+ /* Dump the 5 contiguous QWORD values */
+
+ AcpiDmAddressFields (&Resource->ExtAddress64.Granularity, 64, Level);
+
+ /* Extra field for this descriptor only */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger64 (Resource->ExtAddress64.TypeSpecific,
+ "Type-Specific Attributes");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemory24Descriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Memory24 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMemory24Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory24 (%s,\n",
+ AcpiGbl_RwDecode [ACPI_GET_1BIT_FLAG (Resource->Memory24.Flags)]);
+
+ /* Dump the 4 contiguous WORD values */
+
+ AcpiDmMemoryFields (&Resource->Memory24.Minimum, 16, Level);
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemory32Descriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Memory32 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMemory32Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory32 (%s,\n",
+ AcpiGbl_RwDecode [ACPI_GET_1BIT_FLAG (Resource->Memory32.Flags)]);
+
+ /* Dump the 4 contiguous DWORD values */
+
+ AcpiDmMemoryFields (&Resource->Memory32.Minimum, 32, Level);
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedMemory32Descriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Fixed Memory32 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedMemory32Descriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory32Fixed (%s,\n",
+ AcpiGbl_RwDecode [ACPI_GET_1BIT_FLAG (Resource->FixedMemory32.Flags)]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger32 (Resource->FixedMemory32.Address,
+ "Address Base");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger32 (Resource->FixedMemory32.AddressLength,
+ "Address Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGenericRegisterDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Generic Register descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmGenericRegisterDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Register (");
+ AcpiDmAddressSpace (Resource->GenericReg.AddressSpaceId);
+ AcpiOsPrintf ("\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->GenericReg.BitWidth, "Bit Width");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->GenericReg.BitOffset, "Bit Offset");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger64 (Resource->GenericReg.Address, "Address");
+
+ /* Optional field for ACPI 3.0 */
+
+ AcpiDmIndent (Level + 1);
+ if (Resource->GenericReg.AccessSize)
+ {
+ AcpiOsPrintf ("0x%2.2X, // %s\n",
+ Resource->GenericReg.AccessSize, "Access Size");
+ AcpiDmIndent (Level + 1);
+ }
+ else
+ {
+ AcpiOsPrintf (",");
+ }
+
+ /* DescriptorName was added for ACPI 3.0+ */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmInterruptDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a extended Interrupt descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmInterruptDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Interrupt (%s, %s, %s, %s, ",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Resource->ExtendedIrq.Flags)],
+ AcpiGbl_HeDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->ExtendedIrq.Flags, 1)],
+ AcpiGbl_LlDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->ExtendedIrq.Flags, 2)],
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->ExtendedIrq.Flags, 3)]);
+
+ /*
+ * The ResourceSource fields are optional and appear after the interrupt
+ * list. Must compute length based on length of the list. First xrupt
+ * is included in the struct (reason for -1 below)
+ */
+ AcpiDmResourceSource (Resource,
+ sizeof (AML_RESOURCE_EXTENDED_IRQ) +
+ ((UINT32) Resource->ExtendedIrq.InterruptCount - 1) * sizeof (UINT32),
+ Resource->ExtendedIrq.ResourceLength);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ /* Dump the interrupt list */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+ for (i = 0; i < Resource->ExtendedIrq.InterruptCount; i++)
+ {
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%8.8X,\n",
+ (UINT32) Resource->ExtendedIrq.Interrupts[i]);
+ }
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorCommon
+ *
+ * PARAMETERS: Name - Descriptor name suffix
+ * ByteData - Pointer to the vendor byte data
+ * Length - Length of the byte data
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor descriptor, both Large and Small
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorCommon (
+ const char *Name,
+ UINT8 *ByteData,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump macro name */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Vendor%s (", Name);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (") // Length = 0x%.2X\n", Length);
+
+ /* Dump the vendor bytes */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+
+ AcpiDmDisasmByteList (Level + 1, ByteData, Length);
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorLargeDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor Large descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorLargeDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmVendorCommon ("Long ",
+ ACPI_ADD_PTR (UINT8, Resource, sizeof (AML_RESOURCE_LARGE_HEADER)),
+ Length, Level);
+}
diff --git a/usr/src/common/acpica/disassembler/dmresrcl2.c b/usr/src/common/acpica/disassembler/dmresrcl2.c
new file mode 100644
index 0000000000..2e3273113c
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmresrcl2.c
@@ -0,0 +1,750 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcl2.c - "Large" Resource Descriptor disassembly (#2)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "acdisasm.h"
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcl2")
+
+/* Local prototypes */
+
+static void
+AcpiDmI2cSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmSpiSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmUartSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmGpioCommon (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Level);
+
+static void
+AcpiDmDumpRawDataBuffer (
+ UINT8 *Buffer,
+ UINT32 Length,
+ UINT32 Level);
+
+
+/* Dispatch table for the serial bus descriptors */
+
+static ACPI_RESOURCE_HANDLER SerialBusResourceDispatch [] =
+{
+ NULL,
+ AcpiDmI2cSerialBusDescriptor,
+ AcpiDmSpiSerialBusDescriptor,
+ AcpiDmUartSerialBusDescriptor
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpRawDataBuffer
+ *
+ * PARAMETERS: Buffer - Pointer to the data bytes
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a data buffer as a RawDataBuffer() object. Used for
+ * vendor data bytes.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmDumpRawDataBuffer (
+ UINT8 *Buffer,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 Index;
+ UINT32 i;
+ UINT32 j;
+
+
+ if (!Length)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("RawDataBuffer (0x%.2X) // Vendor Data", Length);
+
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("{\n");
+ AcpiDmIndent (Level + 2);
+
+ for (i = 0; i < Length;)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ Index = i + j;
+ if (Index >= Length)
+ {
+ goto Finish;
+ }
+
+ AcpiOsPrintf ("0x%2.2X", Buffer[Index]);
+ if ((Index + 1) >= Length)
+ {
+ goto Finish;
+ }
+
+ AcpiOsPrintf (", ");
+ }
+
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 2);
+
+ i += 8;
+ }
+
+Finish:
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("}");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioCommon
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode common parts of a GPIO Interrupt descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioCommon (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Level)
+{
+ UINT16 *PinList;
+ UINT8 *VendorData;
+ char *DeviceName = NULL;
+ UINT32 PinCount;
+ UINT32 i;
+
+
+ /* ResourceSource, ResourceSourceIndex, ResourceType */
+
+ AcpiDmIndent (Level + 1);
+ if (Resource->Gpio.ResSourceOffset)
+ {
+ DeviceName = ACPI_ADD_PTR (char,
+ Resource, Resource->Gpio.ResSourceOffset),
+ AcpiUtPrintString (DeviceName, ACPI_UINT16_MAX);
+ }
+
+ AcpiOsPrintf (", ");
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.ResSourceIndex);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [ACPI_GET_1BIT_FLAG (Resource->Gpio.Flags)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",");
+
+ /* Dump the vendor data */
+
+ if (Resource->Gpio.VendorOffset)
+ {
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ Resource->Gpio.VendorOffset);
+
+ AcpiDmDumpRawDataBuffer (VendorData,
+ Resource->Gpio.VendorLength, Level);
+ }
+
+ AcpiOsPrintf (")\n");
+
+ /* Dump the interrupt list */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("{ // Pin list\n");
+
+ PinCount = ((UINT32) (Resource->Gpio.ResSourceOffset -
+ Resource->Gpio.PinTableOffset)) /
+ sizeof (UINT16);
+
+ PinList = (UINT16 *) ACPI_ADD_PTR (char, Resource,
+ Resource->Gpio.PinTableOffset);
+
+ for (i = 0; i < PinCount; i++)
+ {
+ AcpiDmIndent (Level + 2);
+ AcpiOsPrintf ("0x%4.4X%s\n", PinList[i],
+ ((i + 1) < PinCount) ? "," : "");
+ }
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("}\n");
+
+#ifdef ACPI_APPLICATION
+ MpSaveGpioInfo (Info->MappingOp, Resource,
+ PinCount, PinList, DeviceName);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioIntDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GPIO Interrupt descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioIntDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump the GpioInt-specific portion of the descriptor */
+
+ /* EdgeLevel, ActiveLevel, Shared */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("GpioInt (%s, %s, %s, ",
+ AcpiGbl_HeDecode [ACPI_GET_1BIT_FLAG (Resource->Gpio.IntFlags)],
+ AcpiGbl_LlDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Gpio.IntFlags, 1)],
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Gpio.IntFlags, 3)]);
+
+ /* PinConfig, DebounceTimeout */
+
+ if (Resource->Gpio.PinConfig <= 3)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_PpcDecode[Resource->Gpio.PinConfig]);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.PinConfig);
+ }
+ AcpiOsPrintf ("0x%4.4X,\n", Resource->Gpio.DebounceTimeout);
+
+ /* Dump the GpioInt/GpioIo common portion of the descriptor */
+
+ AcpiDmGpioCommon (Info, Resource, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioIoDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GPIO I/O descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioIoDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump the GpioIo-specific portion of the descriptor */
+
+ /* Shared, PinConfig */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("GpioIo (%s, ",
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Gpio.IntFlags, 3)]);
+
+ if (Resource->Gpio.PinConfig <= 3)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_PpcDecode[Resource->Gpio.PinConfig]);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.PinConfig);
+ }
+
+ /* DebounceTimeout, DriveStrength, IoRestriction */
+
+ AcpiOsPrintf ("0x%4.4X, ", Resource->Gpio.DebounceTimeout);
+ AcpiOsPrintf ("0x%4.4X, ", Resource->Gpio.DriveStrength);
+ AcpiOsPrintf ("%s,\n",
+ AcpiGbl_IorDecode [ACPI_GET_2BIT_FLAG (Resource->Gpio.IntFlags)]);
+
+ /* Dump the GpioInt/GpioIo common portion of the descriptor */
+
+ AcpiDmGpioCommon (Info, Resource, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GpioInt/GpioIo GPIO Interrupt/IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmGpioDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT8 ConnectionType;
+
+
+ ConnectionType = Resource->Gpio.ConnectionType;
+
+ switch (ConnectionType)
+ {
+ case AML_RESOURCE_GPIO_TYPE_INT:
+
+ AcpiDmGpioIntDescriptor (Info, Resource, Length, Level);
+ break;
+
+ case AML_RESOURCE_GPIO_TYPE_IO:
+
+ AcpiDmGpioIoDescriptor (Info, Resource, Length, Level);
+ break;
+
+ default:
+
+ AcpiOsPrintf ("Unknown GPIO type\n");
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpSerialBusVendorData
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump optional serial bus vendor data
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmDumpSerialBusVendorData (
+ AML_RESOURCE *Resource,
+ UINT32 Level)
+{
+ UINT8 *VendorData;
+ UINT32 VendorLength;
+
+
+ /* Get the (optional) vendor data and length */
+
+ switch (Resource->CommonSerialBus.Type)
+ {
+ case AML_RESOURCE_I2C_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_I2C_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_I2C_SERIALBUS));
+ break;
+
+ case AML_RESOURCE_SPI_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_SPI_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_SPI_SERIALBUS));
+ break;
+
+ case AML_RESOURCE_UART_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_UART_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_UART_SERIALBUS));
+ break;
+
+ default:
+
+ return;
+ }
+
+ /* Dump the vendor bytes as a RawDataBuffer object */
+
+ AcpiDmDumpRawDataBuffer (VendorData, VendorLength, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmI2cSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a I2C serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmI2cSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+ char *DeviceName;
+
+
+ /* SlaveAddress, SlaveMode, ConnectionSpeed, AddressingMode */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("I2cSerialBusV2 (0x%4.4X, %s, 0x%8.8X,\n",
+ Resource->I2cSerialBus.SlaveAddress,
+ AcpiGbl_SmDecode [ACPI_GET_1BIT_FLAG (Resource->I2cSerialBus.Flags)],
+ Resource->I2cSerialBus.ConnectionSpeed);
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_AmDecode [ACPI_GET_1BIT_FLAG (Resource->I2cSerialBus.TypeSpecificFlags)]);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ DeviceName = ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ AcpiUtPrintString (DeviceName, ACPI_UINT16_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->I2cSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->I2cSerialBus.Flags, 1)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Share */
+
+ AcpiOsPrintf (", %s,\n",
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->I2cSerialBus.Flags, 2)]);
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
+#ifdef ACPI_APPLICATION
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSpiSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a SPI serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmSpiSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+ char *DeviceName;
+
+
+ /* DeviceSelection, DeviceSelectionPolarity, WireMode, DataBitLength */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("SpiSerialBusV2 (0x%4.4X, %s, %s, 0x%2.2X,\n",
+ Resource->SpiSerialBus.DeviceSelection,
+ AcpiGbl_DpDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->SpiSerialBus.TypeSpecificFlags, 1)],
+ AcpiGbl_WmDecode [ACPI_GET_1BIT_FLAG (Resource->SpiSerialBus.TypeSpecificFlags)],
+ Resource->SpiSerialBus.DataBitLength);
+
+ /* SlaveMode, ConnectionSpeed, ClockPolarity, ClockPhase */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, 0x%8.8X, %s,\n",
+ AcpiGbl_SmDecode [ACPI_GET_1BIT_FLAG (Resource->SpiSerialBus.Flags)],
+ Resource->SpiSerialBus.ConnectionSpeed,
+ AcpiGbl_CpoDecode [ACPI_GET_1BIT_FLAG (Resource->SpiSerialBus.ClockPolarity)]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_CphDecode [ACPI_GET_1BIT_FLAG (Resource->SpiSerialBus.ClockPhase)]);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ DeviceName = ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ AcpiUtPrintString (DeviceName, ACPI_UINT16_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->SpiSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->SpiSerialBus.Flags, 1)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Share */
+
+ AcpiOsPrintf (", %s,\n",
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->SpiSerialBus.Flags, 2)]);
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
+#ifdef ACPI_APPLICATION
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUartSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a UART serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUartSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+ char *DeviceName;
+
+
+ /* ConnectionSpeed, BitsPerByte, StopBits */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("UartSerialBusV2 (0x%8.8X, %s, %s,\n",
+ Resource->UartSerialBus.DefaultBaudRate,
+ AcpiGbl_BpbDecode [ACPI_EXTRACT_3BIT_FLAG (Resource->UartSerialBus.TypeSpecificFlags, 4)],
+ AcpiGbl_SbDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->UartSerialBus.TypeSpecificFlags, 2)]);
+
+ /* LinesInUse, IsBigEndian, Parity, FlowControl */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, %s, %s, %s,\n",
+ Resource->UartSerialBus.LinesEnabled,
+ AcpiGbl_EdDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->UartSerialBus.TypeSpecificFlags, 7)],
+ AcpiGbl_PtDecode [ACPI_GET_3BIT_FLAG (Resource->UartSerialBus.Parity)],
+ AcpiGbl_FcDecode [ACPI_GET_2BIT_FLAG (Resource->UartSerialBus.TypeSpecificFlags)]);
+
+ /* ReceiveBufferSize, TransmitBufferSize */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%4.4X, 0x%4.4X, ",
+ Resource->UartSerialBus.RxFifoSize,
+ Resource->UartSerialBus.TxFifoSize);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ DeviceName = ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ AcpiUtPrintString (DeviceName, ACPI_UINT16_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->UartSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->UartSerialBus.Flags, 1)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Share */
+
+ AcpiOsPrintf (", %s,\n",
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->UartSerialBus.Flags, 2)]);
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+
+#ifdef ACPI_APPLICATION
+ MpSaveSerialInfo (Info->MappingOp, Resource, DeviceName);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSerialBusDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a I2C/SPI/UART serial bus descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmSerialBusDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ SerialBusResourceDispatch [Resource->CommonSerialBus.Type] (
+ Info, Resource, Length, Level);
+}
diff --git a/usr/src/common/acpica/disassembler/dmresrcs.c b/usr/src/common/acpica/disassembler/dmresrcs.c
new file mode 100644
index 0000000000..c601f36492
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmresrcs.c
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcs.c - "Small" Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "acdisasm.h"
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcs")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIrqDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a IRQ descriptor, either Irq() or IrqNoFlags()
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIrqDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("%s (",
+ AcpiGbl_IrqDecode [ACPI_GET_1BIT_FLAG (Length)]);
+
+ /* Decode flags byte if present */
+
+ if (Length & 1)
+ {
+ AcpiOsPrintf ("%s, %s, %s, ",
+ AcpiGbl_HeDecode [ACPI_GET_1BIT_FLAG (Resource->Irq.Flags)],
+ AcpiGbl_LlDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->Irq.Flags, 3)],
+ AcpiGbl_ShrDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Irq.Flags, 4)]);
+ }
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmBitList (Resource->Irq.IrqMask);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDmaDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a DMA descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDmaDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("DMA (%s, %s, %s, ",
+ AcpiGbl_TypDecode [ACPI_EXTRACT_2BIT_FLAG (Resource->Dma.Flags, 5)],
+ AcpiGbl_BmDecode [ACPI_EXTRACT_1BIT_FLAG (Resource->Dma.Flags, 2)],
+ AcpiGbl_SizDecode [ACPI_GET_2BIT_FLAG (Resource->Dma.Flags)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmBitList (Resource->Dma.DmaChannelMask);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedDmaDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a FixedDMA descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedDmaDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("FixedDMA (0x%4.4X, 0x%4.4X, ",
+ Resource->FixedDma.RequestLines,
+ Resource->FixedDma.Channels);
+
+ if (Resource->FixedDma.Width <= 5)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_DtsDecode [Resource->FixedDma.Width]);
+ }
+ else
+ {
+ AcpiOsPrintf ("%X /* INVALID DMA WIDTH */, ",
+ Resource->FixedDma.Width);
+ }
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode an IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIoDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("IO (%s,\n",
+ AcpiGbl_IoDecode [ACPI_GET_1BIT_FLAG (Resource->Io.Flags)]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->Io.Minimum, "Range Minimum");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->Io.Maximum, "Range Maximum");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->Io.Alignment, "Alignment");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->Io.AddressLength, "Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedIoDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Fixed IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedIoDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("FixedIO (\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->FixedIo.Address, "Address");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->FixedIo.AddressLength, "Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmStartDependentDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Start Dependendent functions descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmStartDependentDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+
+ if (Length & 1)
+ {
+ AcpiOsPrintf ("StartDependentFn (0x%2.2X, 0x%2.2X)\n",
+ (UINT32) ACPI_GET_2BIT_FLAG (Resource->StartDpf.Flags),
+ (UINT32) ACPI_EXTRACT_2BIT_FLAG (Resource->StartDpf.Flags, 2));
+ }
+ else
+ {
+ AcpiOsPrintf ("StartDependentFnNoPri ()\n");
+ }
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmEndDependentDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode an End Dependent functions descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmEndDependentDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("EndDependentFn ()\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorSmallDescriptor
+ *
+ * PARAMETERS: Info - Extra resource info
+ * Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor Small Descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorSmallDescriptor (
+ ACPI_OP_WALK_INFO *Info,
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmVendorCommon ("Short",
+ ACPI_ADD_PTR (UINT8, Resource, sizeof (AML_RESOURCE_SMALL_HEADER)),
+ Length, Level);
+}
diff --git a/usr/src/common/acpica/disassembler/dmutils.c b/usr/src/common/acpica/disassembler/dmutils.c
new file mode 100644
index 0000000000..02717bc6ad
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmutils.c
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ *
+ * Module Name: dmutils - AML disassembler utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "amlcode.h"
+#include "acdisasm.h"
+
+#ifdef ACPI_ASL_COMPILER
+#include <acnamesp.h>
+#endif
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmutils")
+
+
+/* Data used in keeping track of fields */
+#if 0
+const char *AcpiGbl_FENames[] =
+{
+ "skip",
+ "?access?"
+}; /* FE = Field Element */
+#endif
+
+/* Operators for Match() */
+
+const char *AcpiGbl_MatchOps[] =
+{
+ "MTR",
+ "MEQ",
+ "MLE",
+ "MLT",
+ "MGE",
+ "MGT"
+};
+
+/* Access type decoding */
+
+const char *AcpiGbl_AccessTypes[] =
+{
+ "AnyAcc",
+ "ByteAcc",
+ "WordAcc",
+ "DWordAcc",
+ "QWordAcc",
+ "BufferAcc",
+ "InvalidAccType",
+ "InvalidAccType"
+};
+
+/* Lock rule decoding */
+
+const char *AcpiGbl_LockRule[] =
+{
+ "NoLock",
+ "Lock"
+};
+
+/* Update rule decoding */
+
+const char *AcpiGbl_UpdateRules[] =
+{
+ "Preserve",
+ "WriteAsOnes",
+ "WriteAsZeros",
+ "InvalidUpdateRule"
+};
+
+/* Strings used to decode resource descriptors */
+
+const char *AcpiGbl_WordDecode[] =
+{
+ "Memory",
+ "IO",
+ "BusNumber",
+ "UnknownResourceType"
+};
+
+const char *AcpiGbl_IrqDecode[] =
+{
+ "IRQNoFlags",
+ "IRQ"
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDecodeAttribute
+ *
+ * PARAMETERS: Attribute - Attribute field of AccessAs keyword
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the AccessAs attribute byte. (Mostly SMBus and
+ * GenericSerialBus stuff.)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDecodeAttribute (
+ UINT8 Attribute)
+{
+
+ switch (Attribute)
+ {
+ case AML_FIELD_ATTRIB_QUICK:
+
+ AcpiOsPrintf ("AttribQuick");
+ break;
+
+ case AML_FIELD_ATTRIB_SEND_RCV:
+
+ AcpiOsPrintf ("AttribSendReceive");
+ break;
+
+ case AML_FIELD_ATTRIB_BYTE:
+
+ AcpiOsPrintf ("AttribByte");
+ break;
+
+ case AML_FIELD_ATTRIB_WORD:
+
+ AcpiOsPrintf ("AttribWord");
+ break;
+
+ case AML_FIELD_ATTRIB_BLOCK:
+
+ AcpiOsPrintf ("AttribBlock");
+ break;
+
+ case AML_FIELD_ATTRIB_MULTIBYTE:
+
+ AcpiOsPrintf ("AttribBytes");
+ break;
+
+ case AML_FIELD_ATTRIB_WORD_CALL:
+
+ AcpiOsPrintf ("AttribProcessCall");
+ break;
+
+ case AML_FIELD_ATTRIB_BLOCK_CALL:
+
+ AcpiOsPrintf ("AttribBlockProcessCall");
+ break;
+
+ case AML_FIELD_ATTRIB_RAW_BYTES:
+
+ AcpiOsPrintf ("AttribRawBytes");
+ break;
+
+ case AML_FIELD_ATTRIB_RAW_PROCESS:
+
+ AcpiOsPrintf ("AttribRawProcessBytes");
+ break;
+
+ default:
+
+ /* A ByteConst is allowed by the grammar */
+
+ AcpiOsPrintf ("0x%2.2X", Attribute);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIndent
+ *
+ * PARAMETERS: Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Indent 4 spaces per indentation level.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIndent (
+ UINT32 Level)
+{
+
+ if (!Level)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("%*.s", (Level * 4), " ");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCommaIfListMember
+ *
+ * PARAMETERS: Op - Current operator/operand
+ *
+ * RETURN: TRUE if a comma was inserted
+ *
+ * DESCRIPTION: Insert a comma if this Op is a member of an argument list.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmCommaIfListMember (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (!Op->Common.Next)
+ {
+ return (FALSE);
+ }
+
+ 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) &&
+ (!Op->Common.Next->Common.Value.String))
+ {
+ /*
+ * To handle the Divide() case where there are two optional
+ * targets, look ahead one more op. If null, this null target
+ * is the one and only target -- no comma needed. Otherwise,
+ * we need a comma to prepare for the next target.
+ */
+ if (!Op->Common.Next->Common.Next)
+ {
+ return (FALSE);
+ }
+ }
+
+ if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) &&
+ (!(Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)))
+ {
+ return (FALSE);
+ }
+
+ /* Emit comma only if this is not a C-style operator */
+
+ if (!Op->Common.OperatorSymbol)
+ {
+ AcpiOsPrintf (", ");
+ }
+
+ return (TRUE);
+ }
+
+ else if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) &&
+ (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST))
+ {
+ AcpiOsPrintf (", ");
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCommaIfFieldMember
+ *
+ * PARAMETERS: Op - Current operator/operand
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a comma if this Op is a member of a Field argument list.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCommaIfFieldMember (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (Op->Common.Next)
+ {
+ AcpiOsPrintf (", ");
+ }
+}
diff --git a/usr/src/common/acpica/disassembler/dmwalk.c b/usr/src/common/acpica/disassembler/dmwalk.c
new file mode 100644
index 0000000000..3c953f5465
--- /dev/null
+++ b/usr/src/common/acpica/disassembler/dmwalk.c
@@ -0,0 +1,1100 @@
+/*******************************************************************************
+ *
+ * Module Name: dmwalk - AML disassembly tree walk
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2016, 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 "acdebug.h"
+
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmwalk")
+
+
+#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
+AcpiDmDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDmAscendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static UINT32
+AcpiDmBlockType (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisassemble
+ *
+ * PARAMETERS: WalkState - Current state
+ * Origin - Starting object
+ * NumOpcodes - Max number of opcodes to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Disassemble parser object and its children. This is the
+ * main entry point of the disassembler.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisassemble (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Origin,
+ UINT32 NumOpcodes)
+{
+ ACPI_PARSE_OBJECT *Op = Origin;
+ ACPI_OP_WALK_INFO Info;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ memset (&Info, 0, sizeof (ACPI_OP_WALK_INFO));
+ Info.WalkState = WalkState;
+ Info.StartAml = Op->Common.Aml - sizeof (ACPI_TABLE_HEADER);
+ Info.AmlOffset = Op->Common.Aml - Info.StartAml;
+
+ AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmWalkParseTree
+ *
+ * PARAMETERS: Op - Root Op object
+ * DescendingCallback - Called during tree descent
+ * AscendingCallback - Called during tree ascent
+ * Context - To be passed to the callbacks
+ *
+ * RETURN: Status from callback(s)
+ *
+ * DESCRIPTION: Walk the entire parse tree.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmWalkParseTree (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_WALK_CALLBACK DescendingCallback,
+ ASL_WALK_CALLBACK AscendingCallback,
+ void *Context)
+{
+ BOOLEAN NodePreviouslyVisited;
+ ACPI_PARSE_OBJECT *StartOp = Op;
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_OP_WALK_INFO *Info = Context;
+
+
+ Info->Level = 0;
+ NodePreviouslyVisited = FALSE;
+
+ while (Op)
+ {
+ if (NodePreviouslyVisited)
+ {
+ if (AscendingCallback)
+ {
+ Status = AscendingCallback (Op, Info->Level, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+ }
+ else
+ {
+ /* Let the callback process the node */
+
+ Status = DescendingCallback (Op, Info->Level, Context);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Visit children first, once */
+
+ Next = AcpiPsGetArg (Op, 0);
+ if (Next)
+ {
+ Info->Level++;
+ Op = Next;
+ continue;
+ }
+ }
+ else if (Status != AE_CTRL_DEPTH)
+ {
+ /* Exit immediately on any error */
+
+ return;
+ }
+ }
+
+ /* Terminate walk at start op */
+
+ if (Op == StartOp)
+ {
+ break;
+ }
+
+ /* No more children, re-visit this node */
+
+ if (!NodePreviouslyVisited)
+ {
+ NodePreviouslyVisited = TRUE;
+ continue;
+ }
+
+ /* No more children, visit peers */
+
+ if (Op->Common.Next)
+ {
+ Op = Op->Common.Next;
+ NodePreviouslyVisited = FALSE;
+ }
+ else
+ {
+ /* No peers, re-visit parent */
+
+ if (Info->Level != 0 )
+ {
+ Info->Level--;
+ }
+
+ Op = Op->Common.Parent;
+ NodePreviouslyVisited = TRUE;
+ }
+ }
+
+ /* If we get here, the walk completed with no errors */
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmBlockType
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: BlockType - not a block, parens, braces, or even both.
+ *
+ * DESCRIPTION: Type of block for this op (parens or braces)
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDmBlockType (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ if (!Op)
+ {
+ return (BLOCK_NONE);
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ELSE_OP:
+
+ return (BLOCK_BRACE);
+
+ case AML_METHOD_OP:
+ case AML_DEVICE_OP:
+ case AML_SCOPE_OP:
+ case AML_PROCESSOR_OP:
+ case AML_POWER_RES_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+
+ return (BLOCK_PAREN | BLOCK_BRACE);
+
+ case AML_BUFFER_OP:
+
+ if ((Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) ||
+ (Op->Common.DisasmOpcode == ACPI_DASM_UUID) ||
+ (Op->Common.DisasmOpcode == ACPI_DASM_PLD_METHOD))
+ {
+ return (BLOCK_NONE);
+ }
+
+ /*lint -fallthrough */
+
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ return (BLOCK_PAREN | BLOCK_BRACE);
+
+ case AML_EVENT_OP:
+
+ 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);
+ }
+
+ /*lint -fallthrough */
+
+ default:
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ return (BLOCK_PAREN);
+ }
+
+ return (BLOCK_NONE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmListType
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: ListType - has commas or not.
+ *
+ * DESCRIPTION: Type of block for this op (parens or braces)
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmListType (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ if (!Op)
+ {
+ return (BLOCK_NONE);
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+
+ case AML_ELSE_OP:
+ case AML_METHOD_OP:
+ case AML_DEVICE_OP:
+ case AML_SCOPE_OP:
+ case AML_POWER_RES_OP:
+ case AML_PROCESSOR_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+
+ return (BLOCK_NONE);
+
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ return (BLOCK_COMMA_LIST);
+
+ default:
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ return (BLOCK_COMMA_LIST);
+ }
+
+ return (BLOCK_NONE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDescendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: First visitation of a parse object during tree descent.
+ * Decode opcode name and begin parameter list(s), if any.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 Name;
+ ACPI_PARSE_OBJECT *NextOp;
+ ACPI_PARSE_OBJECT *NextOp2;
+ UINT32 AmlOffset;
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /* Listing support to dump the AML code after the ASL statement */
+
+ if (AcpiGbl_DmOpt_Listing)
+ {
+ /* We only care about these classes of objects */
+
+ if ((OpInfo->Class == AML_CLASS_NAMED_OBJECT) ||
+ (OpInfo->Class == AML_CLASS_CONTROL) ||
+ (OpInfo->Class == AML_CLASS_CREATE) ||
+ ((OpInfo->Class == AML_CLASS_EXECUTE) && (!Op->Common.Next)))
+ {
+ if (AcpiGbl_DmOpt_Listing && Info->PreviousAml)
+ {
+ /* Dump the AML byte code for the previous Op */
+
+ if (Op->Common.Aml > Info->PreviousAml)
+ {
+ AcpiOsPrintf ("\n");
+ AcpiUtDumpBuffer (
+ (Info->StartAml + Info->AmlOffset),
+ (Op->Common.Aml - Info->PreviousAml),
+ DB_BYTE_DISPLAY, Info->AmlOffset);
+ AcpiOsPrintf ("\n");
+ }
+
+ Info->AmlOffset = (Op->Common.Aml - Info->StartAml);
+ }
+
+ Info->PreviousAml = Op->Common.Aml;
+ }
+ }
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
+ {
+ /* Ignore this op -- it was handled elsewhere */
+
+ return (AE_CTRL_DEPTH);
+ }
+
+ if (Op->Common.AmlOpcode == AML_IF_OP)
+ {
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (NextOp)
+ {
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+
+ /* Don't emit the actual embedded externals unless asked */
+
+ if (!AcpiGbl_DmEmitExternalOpcodes)
+ {
+ /*
+ * A Zero predicate indicates the possibility of one or more
+ * External() opcodes within the If() block.
+ */
+ if (NextOp->Common.AmlOpcode == AML_ZERO_OP)
+ {
+ NextOp2 = NextOp->Common.Next;
+
+ if (NextOp2 &&
+ (NextOp2->Common.AmlOpcode == AML_EXTERNAL_OP))
+ {
+ /* Ignore the If 0 block and all children */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (AE_CTRL_DEPTH);
+ }
+ }
+ }
+ }
+ }
+
+ /* Level 0 is at the Definition Block level */
+
+ if (Level == 0)
+ {
+ /* In verbose mode, print the AML offset, opcode and depth count */
+
+ if (Info->WalkState)
+ {
+ AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml,
+ Info->WalkState->ParserState.AmlStart);
+ if (AcpiGbl_DmOpt_Verbose)
+ {
+ AcpiOsPrintf (DB_FULL_OP_INFO,
+ (Info->WalkState->MethodNode ?
+ Info->WalkState->MethodNode->Name.Ascii : " "),
+ AmlOffset, (UINT32) Op->Common.AmlOpcode);
+ }
+ }
+
+ if (Op->Common.AmlOpcode == AML_SCOPE_OP)
+ {
+ /* This is the beginning of the Definition Block */
+
+ AcpiOsPrintf ("{\n");
+
+ /* Emit all External() declarations here */
+
+ AcpiDmEmitExternals ();
+ return (AE_OK);
+ }
+ }
+ else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list,
+ * indent a new line
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_NOOP_OP:
+ /*
+ * Optionally just ignore this opcode. Some tables use
+ * NoOp opcodes for "padding" out packages that the BIOS
+ * changes dynamically. This can leave hundreds or
+ * thousands of NoOp opcodes that if disassembled,
+ * cannot be compiled because they are syntactically
+ * incorrect.
+ */
+ if (AcpiGbl_IgnoreNoopOperator)
+ {
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (AE_OK);
+ }
+
+ /* Fallthrough */
+
+ default:
+
+ AcpiDmIndent (Level);
+ break;
+ }
+
+ Info->LastLevel = Level;
+ Info->Count = 0;
+ }
+
+ /*
+ * This is an inexpensive mechanism to try and keep lines from getting
+ * too long. When the limit is hit, start a new line at the previous
+ * indent plus one. A better but more expensive mechanism would be to
+ * keep track of the current column.
+ */
+ Info->Count++;
+ 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);
+
+ if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) ||
+ (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP))
+ {
+ return (AE_OK);
+ }
+
+ if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
+ (Op->Common.AmlOpcode == AML_RETURN_OP))
+ {
+ Info->Level--;
+ }
+
+ /* Start the opcode argument list if necessary */
+
+ if ((OpInfo->Flags & AML_HAS_ARGS) ||
+ (Op->Common.AmlOpcode == AML_EVENT_OP))
+ {
+ /* This opcode has an argument list */
+
+ if (AcpiDmBlockType (Op) & BLOCK_PAREN)
+ {
+ AcpiOsPrintf (" (");
+ }
+
+ /* If this is a named opcode, print the associated name value */
+
+ if (OpInfo->Flags & AML_NAMED)
+ {
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ALIAS_OP:
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+
+ /*lint -fallthrough */
+
+ default:
+
+ Name = AcpiPsGetName (Op);
+ if (Op->Named.Path)
+ {
+ AcpiDmNamestring ((char *) Op->Named.Path);
+ }
+ else
+ {
+ AcpiDmDumpName (Name);
+ }
+
+ if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
+ {
+ if (AcpiGbl_DmOpt_Verbose)
+ {
+ (void) AcpiPsDisplayObjectPathname (NULL, Op);
+ }
+ }
+ break;
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_METHOD_OP:
+
+ AcpiDmMethodFlags (Op);
+ AcpiOsPrintf (")");
+
+ /* Emit description comment for Method() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op);
+ break;
+
+ case AML_NAME_OP:
+
+ /* Check for _HID and related EISAID() */
+
+ AcpiDmCheckForHardwareId (Op);
+ 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 */
+
+ AcpiOsPrintf (", ");
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+ return (AE_OK);
+
+ case AML_PROCESSOR_OP:
+
+ /* Mark the next three Ops as part of the parameter list */
+
+ AcpiOsPrintf (", ");
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+ 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:
+
+ AcpiOsPrintf (")");
+ break;
+
+ default:
+
+ AcpiOsPrintf ("*** Unhandled named opcode %X\n",
+ Op->Common.AmlOpcode);
+ break;
+ }
+ }
+
+ else switch (Op->Common.AmlOpcode)
+ {
+ case AML_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+
+ Info->BitOffset = 0;
+
+ /* Name of the parent OperationRegion */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_BANK_FIELD_OP:
+
+ /* Namestring - Bank Name */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiOsPrintf (", ");
+
+ /*
+ * Bank Value. This is a TermArg in the middle of the parameter
+ * list, must handle it here.
+ *
+ * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMETER_LIST
+ * eliminates newline in the output.
+ */
+ NextOp = NextOp->Common.Next;
+
+ Info->Flags = ACPI_PARSEOP_PARAMETER_LIST;
+ AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp,
+ AcpiDmAscendingOp, Info);
+ Info->Flags = 0;
+ Info->Level = Level;
+
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiOsPrintf (", ");
+ break;
+
+ case AML_INDEX_FIELD_OP:
+
+ /* Namestring - Data Name */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ break;
+
+ default:
+
+ break;
+ }
+
+ AcpiDmFieldFlags (NextOp);
+ break;
+
+ case AML_BUFFER_OP:
+
+ /* The next op is the size parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (!NextOp)
+ {
+ /* Single-step support */
+
+ return (AE_OK);
+ }
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
+ {
+ /*
+ * We have a resource list. Don't need to output
+ * the buffer size Op. Open up a new block
+ */
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ NextOp = NextOp->Common.Next;
+ AcpiOsPrintf (")");
+
+ /* Emit description comment for Name() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op->Asl.Parent);
+
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Info->Level);
+ AcpiOsPrintf ("{\n");
+ return (AE_OK);
+ }
+
+ /* Normal Buffer, mark size as in the parameter list */
+
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+ return (AE_OK);
+
+ case AML_IF_OP:
+ case AML_VAR_PACKAGE_OP:
+ case AML_WHILE_OP:
+
+ /* The next op is the size or predicate parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (NextOp)
+ {
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+ }
+ return (AE_OK);
+
+ case AML_PACKAGE_OP:
+
+ /* The next op is the size parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (NextOp)
+ {
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
+ }
+ return (AE_OK);
+
+ case AML_MATCH_OP:
+
+ AcpiDmMatchOp (Op);
+ break;
+
+ default:
+
+ break;
+ }
+
+ if (AcpiDmBlockType (Op) & BLOCK_BRACE)
+ {
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAscendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Second visitation of a parse object, during ascent of parse
+ * tree. Close out any parameter lists and complete the opcode.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmAscendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ ACPI_PARSE_OBJECT *ParentOp;
+
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
+ {
+ /* Ignore this op -- it was handled elsewhere */
+
+ return (AE_OK);
+ }
+
+ if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
+ {
+ /* Indicates the end of the current descriptor block (table) */
+
+ AcpiOsPrintf ("}\n\n");
+ return (AE_OK);
+ }
+
+ switch (AcpiDmBlockType (Op))
+ {
+ case BLOCK_PAREN:
+
+ /* Completed an op that has arguments, add closing paren if needed */
+
+ AcpiDmCloseOperator (Op);
+
+ if (Op->Common.AmlOpcode == AML_NAME_OP)
+ {
+ /* Emit description comment for Name() with a predefined ACPI name */
+
+ AcpiDmPredefinedDescription (Op);
+ }
+ else
+ {
+ /* For Create* operators, attempt to emit resource tag description */
+
+ AcpiDmFieldPredefinedDescription (Op);
+ }
+
+ /* Decode Notify() values */
+
+ if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
+ {
+ AcpiDmNotifyDescription (Op);
+ }
+
+ AcpiDmDisplayTargetPathname (Op);
+
+ /* Could be a nested operator, check if comma required */
+
+ if (!AcpiDmCommaIfListMember (Op))
+ {
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list
+ * start a new line
+ */
+ if (!(Info->Flags & ACPI_PARSEOP_PARAMETER_LIST))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ }
+ }
+ break;
+
+ case BLOCK_BRACE:
+ case (BLOCK_BRACE | BLOCK_PAREN):
+
+ /* Completed an op that has a term list, add closing brace */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
+ {
+ AcpiOsPrintf ("}");
+ }
+ else
+ {
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}");
+ }
+
+ AcpiDmCommaIfListMember (Op);
+
+ if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
+ {
+ AcpiOsPrintf ("\n");
+ if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
+ {
+ if ((Op->Common.AmlOpcode == AML_IF_OP) &&
+ (Op->Common.Next) &&
+ (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
+ {
+ break;
+ }
+
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!Op->Common.Next))
+ {
+ break;
+ }
+ AcpiOsPrintf ("\n");
+ }
+ }
+ break;
+
+ case BLOCK_NONE:
+ default:
+
+ /* Could be a nested operator, check if comma required */
+
+ if (!AcpiDmCommaIfListMember (Op))
+ {
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list
+ * start a new line
+ */
+ AcpiOsPrintf ("\n");
+ }
+ }
+ else if (Op->Common.Parent)
+ {
+ switch (Op->Common.Parent->Common.AmlOpcode)
+ {
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ break;
+
+ default:
+
+ break;
+ }
+ }
+ break;
+ }
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)
+ {
+ if ((Op->Common.Next) &&
+ (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST))
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * The parent Op is guaranteed to be valid because of the flag
+ * ACPI_PARSEOP_PARAMETER_LIST -- which means that this op is part of
+ * a parameter list and thus has a valid parent.
+ */
+ ParentOp = Op->Common.Parent;
+
+ /*
+ * Just completed a parameter node for something like "Buffer (param)".
+ * Close the paren and open up the term list block with a brace
+ */
+ if (Op->Common.Next)
+ {
+ AcpiOsPrintf (")");
+
+ /*
+ * Emit a description comment for a Name() operator that is a
+ * predefined ACPI name. Must check the grandparent.
+ */
+ ParentOp = ParentOp->Common.Parent;
+ if (ParentOp &&
+ (ParentOp->Asl.AmlOpcode == AML_NAME_OP))
+ {
+ AcpiDmPredefinedDescription (ParentOp);
+ }
+
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level - 1);
+ AcpiOsPrintf ("{\n");
+ }
+ else
+ {
+ ParentOp->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;
+ AcpiOsPrintf (") {");
+ }
+ }
+
+ if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
+ (Op->Common.AmlOpcode == AML_RETURN_OP))
+ {
+ 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);
+}