diff options
author | jkim <jkim@FreeBSD.org> | 2012-02-16 00:24:10 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2012-02-16 00:24:10 +0000 |
commit | a6dfe3119152f97e640cc135d963b9f7c95c84ef (patch) | |
tree | 71526afe7e3c45a4c88ba7b5d8d57d1e469feec2 /source/components/disassembler | |
parent | 4cca06feceaf26d2d8b24e1d834b5ab61208d3fa (diff) | |
download | FreeBSD-src-a6dfe3119152f97e640cc135d963b9f7c95c84ef.zip FreeBSD-src-a6dfe3119152f97e640cc135d963b9f7c95c84ef.tar.gz |
Import ACPICA 20120215.
Diffstat (limited to 'source/components/disassembler')
-rw-r--r-- | source/components/disassembler/dmbuffer.c | 542 | ||||
-rw-r--r-- | source/components/disassembler/dmnames.c | 453 | ||||
-rw-r--r-- | source/components/disassembler/dmobject.c | 589 | ||||
-rw-r--r-- | source/components/disassembler/dmopcode.c | 607 | ||||
-rw-r--r-- | source/components/disassembler/dmresrc.c | 434 | ||||
-rw-r--r-- | source/components/disassembler/dmresrcl.c | 1052 | ||||
-rw-r--r-- | source/components/disassembler/dmresrcl2.c | 700 | ||||
-rw-r--r-- | source/components/disassembler/dmresrcs.c | 358 | ||||
-rw-r--r-- | source/components/disassembler/dmutils.c | 321 | ||||
-rw-r--r-- | source/components/disassembler/dmwalk.c | 935 |
10 files changed, 5991 insertions, 0 deletions
diff --git a/source/components/disassembler/dmbuffer.c b/source/components/disassembler/dmbuffer.c new file mode 100644 index 0000000..9f49f92 --- /dev/null +++ b/source/components/disassembler/dmbuffer.c @@ -0,0 +1,542 @@ +/******************************************************************************* + * + * Module Name: dmbuffer - AML disassembler, buffer and string support + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, 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" +#include "acparser.h" +#include "amlcode.h" + + +#ifdef ACPI_DISASSEMBLER + +#define _COMPONENT ACPI_CA_DEBUGGER + ACPI_MODULE_NAME ("dmbuffer") + +/* Local prototypes */ + +static void +AcpiDmUnicode ( + ACPI_PARSE_OBJECT *Op); + +static void +AcpiDmIsEisaIdElement ( + ACPI_PARSE_OBJECT *Op); + + +/******************************************************************************* + * + * 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; + + + if (!ByteCount) + { + return; + } + + /* Dump the byte list */ + + for (i = 0; i < ByteCount; i++) + { + /* New line every 8 bytes */ + + if (((i % 8) == 0) && (i < ByteCount)) + { + if (i > 0) + { + AcpiOsPrintf ("\n"); + } + + AcpiDmIndent (Level); + if (ByteCount > 8) + { + AcpiOsPrintf ("/* %04X */ ", i); + } + } + + AcpiOsPrintf (" 0x%2.2X", (UINT32) ByteData[i]); + + /* Add comma if there are more bytes to display */ + + if (i < (ByteCount -1)) + { + AcpiOsPrintf (","); + } + } + + if (Level) + { + 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_UINT8_MAX); + AcpiOsPrintf ("\n"); + break; + + case ACPI_DASM_UNICODE: + + AcpiDmUnicode (Op); + break; + + case ACPI_DASM_BUFFER: + default: + + /* + * Not a resource, string, or unicode string. + * Just dump the buffer + */ + AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount); + break; + } +} + + +/******************************************************************************* + * + * 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, 2nd byte must be zero */ + + for (i = 0; i < (ByteCount - 2); i += 2) + { + if ((!ACPI_IS_PRINT (ByteData[i])) || + (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 (!ACPI_IS_PRINT (ByteData[i])) + { + return (FALSE); + } + } + + return (TRUE); +} + + +/******************************************************************************* + * + * 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; + + + /* 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)); + + + AcpiOsPrintf ("\""); + + /* Write every other byte as an ASCII character */ + + for (i = 0; i < (WordCount - 1); i++) + { + AcpiOsPrintf ("%c", (int) WordData[i]); + } + + AcpiOsPrintf ("\")"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmIsEisaIdElement + * + * PARAMETERS: Op - Op to be examined + * + * RETURN: None + * + * DESCRIPTION: Determine if an Op (argument to _HID or _CID) can be converted + * to an EISA ID. + * + ******************************************************************************/ + +static void +AcpiDmIsEisaIdElement ( + ACPI_PARSE_OBJECT *Op) +{ + UINT32 BigEndianId; + UINT32 Prefix[3]; + UINT32 i; + + + /* The parameter must be either a word or a dword */ + + if ((Op->Common.AmlOpcode != AML_DWORD_OP) && + (Op->Common.AmlOpcode != AML_WORD_OP)) + { + return; + } + + /* 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]) || + !ACPI_IS_ALPHA (Prefix[i])) + { + return; + } + } + + /* OK - mark this node as convertable to an EISA ID */ + + Op->Common.DisasmOpcode = ACPI_DASM_EISAID; +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmIsEisaId + * + * PARAMETERS: Op - Op to be examined + * + * RETURN: None + * + * DESCRIPTION: Determine if a Name() Op can be converted to an EisaId. + * + ******************************************************************************/ + +void +AcpiDmIsEisaId ( + 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)) + { + AcpiDmIsEisaIdElement (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) + { + AcpiDmIsEisaIdElement (NextOp); + return; + } + + /* _CID with Package: get the package length */ + + NextOp = AcpiPsGetDepthNext (NULL, NextOp); + + /* Don't need to use the length, just walk the peer list */ + + NextOp = NextOp->Common.Next; + while (NextOp) + { + AcpiDmIsEisaIdElement (NextOp); + NextOp = NextOp->Common.Next; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmEisaId + * + * PARAMETERS: EncodedId - Raw encoded EISA ID. + * + * RETURN: None + * + * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String. + * + ******************************************************************************/ + +void +AcpiDmEisaId ( + UINT32 EncodedId) +{ + UINT32 BigEndianId; + + + /* Swap from little-endian to big-endian to simplify conversion */ + + BigEndianId = AcpiUtDwordByteSwap (EncodedId); + + + /* Split to form "AAANNNN" string */ + + AcpiOsPrintf ("EisaId (\"%c%c%c%4.4X\")", + + /* Three Alpha characters (AAA), 5 bits each */ + + (int) ((BigEndianId >> 26) & 0x1F) + 0x40, + (int) ((BigEndianId >> 21) & 0x1F) + 0x40, + (int) ((BigEndianId >> 16) & 0x1F) + 0x40, + + /* Numeric part (NNNN) is simply the lower 16 bits */ + + (UINT32) (BigEndianId & 0xFFFF)); +} + +#endif diff --git a/source/components/disassembler/dmnames.c b/source/components/disassembler/dmnames.c new file mode 100644 index 0000000..92e67c2 --- /dev/null +++ b/source/components/disassembler/dmnames.c @@ -0,0 +1,453 @@ +/******************************************************************************* + * + * Module Name: dmnames - AML disassembler, names, namestrings, pathnames + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, 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 "acnamesp.h" +#include "acdisasm.h" + + +#ifdef ACPI_DISASSEMBLER + +#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); + 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 (AcpiPsIsPrefixChar (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) && + (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) +{ + + if ((!Name) || + (!Op->Common.Parent)) + { + return; + } + + if (!Op->Common.Node) + { + AcpiOsPrintf ( + " /**** Name not found or not accessible from this scope ****/ "); + } + + ACPI_PARSE_OBJECT *TargetOp; + + + 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 + +#endif + + diff --git a/source/components/disassembler/dmobject.c b/source/components/disassembler/dmobject.c new file mode 100644 index 0000000..cb515e9 --- /dev/null +++ b/source/components/disassembler/dmobject.c @@ -0,0 +1,589 @@ +/******************************************************************************* + * + * Module Name: dmobject - ACPI object decode and display + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, 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 "acnamesp.h" +#include "acdisasm.h" + + +#ifdef ACPI_DISASSEMBLER + +#define _COMPONENT ACPI_CA_DEBUGGER + ACPI_MODULE_NAME ("dmnames") + +/* Local prototypes */ + +static void +AcpiDmDecodeNode ( + ACPI_NAMESPACE_NODE *Node); + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpMethodInfo + * + * PARAMETERS: Status - Method execution status + * WalkState - Current state of the parse tree walk + * Op - Executing parse op + * + * RETURN: None + * + * DESCRIPTION: Called when a method has been aborted because of an error. + * Dumps the method execution stack, and the method locals/args, + * and disassembles the AML opcode that failed. + * + ******************************************************************************/ + +void +AcpiDmDumpMethodInfo ( + ACPI_STATUS Status, + ACPI_WALK_STATE *WalkState, + ACPI_PARSE_OBJECT *Op) +{ + ACPI_PARSE_OBJECT *Next; + ACPI_THREAD_STATE *Thread; + ACPI_WALK_STATE *NextWalkState; + ACPI_NAMESPACE_NODE *PreviousMethod = NULL; + + + /* Ignore control codes, they are not errors */ + + if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL) + { + return; + } + + /* We may be executing a deferred opcode */ + + if (WalkState->DeferredNode) + { + AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); + return; + } + + /* + * If there is no Thread, we are not actually executing a method. + * This can happen when the iASL compiler calls the interpreter + * to perform constant folding. + */ + Thread = WalkState->Thread; + if (!Thread) + { + return; + } + + /* Display exception and method name */ + + AcpiOsPrintf ("\n**** Exception %s during execution of method ", + AcpiFormatException (Status)); + AcpiNsPrintNodePathname (WalkState->MethodNode, NULL); + + /* Display stack of executing methods */ + + AcpiOsPrintf ("\n\nMethod Execution Stack:\n"); + NextWalkState = Thread->WalkStateList; + + /* Walk list of linked walk states */ + + while (NextWalkState) + { + AcpiOsPrintf (" Method [%4.4s] executing: ", + AcpiUtGetNodeName (NextWalkState->MethodNode)); + + /* First method is the currently executing method */ + + if (NextWalkState == WalkState) + { + if (Op) + { + /* Display currently executing ASL statement */ + + Next = Op->Common.Next; + Op->Common.Next = NULL; + + AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX); + Op->Common.Next = Next; + } + } + else + { + /* + * This method has called another method + * NOTE: the method call parse subtree is already deleted at this + * point, so we cannot disassemble the method invocation. + */ + AcpiOsPrintf ("Call to method "); + AcpiNsPrintNodePathname (PreviousMethod, NULL); + } + + PreviousMethod = NextWalkState->MethodNode; + NextWalkState = NextWalkState->Next; + AcpiOsPrintf ("\n"); + } + + /* Display the method locals and arguments */ + + AcpiOsPrintf ("\n"); + AcpiDmDisplayLocals (WalkState); + AcpiOsPrintf ("\n"); + AcpiDmDisplayArguments (WalkState); + AcpiOsPrintf ("\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDecodeInternalObject + * + * PARAMETERS: ObjDesc - Object to be displayed + * + * RETURN: None + * + * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers. + * + ******************************************************************************/ + +void +AcpiDmDecodeInternalObject ( + ACPI_OPERAND_OBJECT *ObjDesc) +{ + UINT32 i; + + + if (!ObjDesc) + { + AcpiOsPrintf (" Uninitialized"); + return; + } + + if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND) + { + AcpiOsPrintf (" %p [%s]", ObjDesc, AcpiUtGetDescriptorName (ObjDesc)); + return; + } + + AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc)); + + switch (ObjDesc->Common.Type) + { + case ACPI_TYPE_INTEGER: + + AcpiOsPrintf (" %8.8X%8.8X", + ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value)); + break; + + + case ACPI_TYPE_STRING: + + AcpiOsPrintf ("(%u) \"%.24s", + ObjDesc->String.Length, ObjDesc->String.Pointer); + + if (ObjDesc->String.Length > 24) + { + AcpiOsPrintf ("..."); + } + else + { + AcpiOsPrintf ("\""); + } + break; + + + case ACPI_TYPE_BUFFER: + + AcpiOsPrintf ("(%u)", ObjDesc->Buffer.Length); + for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++) + { + AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]); + } + break; + + + default: + + AcpiOsPrintf (" %p", ObjDesc); + break; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDecodeNode + * + * PARAMETERS: Node - Object to be displayed + * + * RETURN: None + * + * DESCRIPTION: Short display of a namespace node + * + ******************************************************************************/ + +static void +AcpiDmDecodeNode ( + ACPI_NAMESPACE_NODE *Node) +{ + + AcpiOsPrintf ("<Node> Name %4.4s", + AcpiUtGetNodeName (Node)); + + if (Node->Flags & ANOBJ_METHOD_ARG) + { + AcpiOsPrintf (" [Method Arg]"); + } + if (Node->Flags & ANOBJ_METHOD_LOCAL) + { + AcpiOsPrintf (" [Method Local]"); + } + + switch (Node->Type) + { + /* These types have no attached object */ + + case ACPI_TYPE_DEVICE: + AcpiOsPrintf (" Device"); + break; + + case ACPI_TYPE_THERMAL: + AcpiOsPrintf (" Thermal Zone"); + break; + + default: + AcpiDmDecodeInternalObject (AcpiNsGetAttachedObject (Node)); + break; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDisplayInternalObject + * + * PARAMETERS: ObjDesc - Object to be displayed + * WalkState - Current walk state + * + * RETURN: None + * + * DESCRIPTION: Short display of an internal object + * + ******************************************************************************/ + +void +AcpiDmDisplayInternalObject ( + ACPI_OPERAND_OBJECT *ObjDesc, + ACPI_WALK_STATE *WalkState) +{ + UINT8 Type; + + + AcpiOsPrintf ("%p ", ObjDesc); + + if (!ObjDesc) + { + AcpiOsPrintf ("<Null Object>\n"); + return; + } + + /* Decode the object type */ + + switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) + { + case ACPI_DESC_TYPE_PARSER: + + AcpiOsPrintf ("<Parser> "); + break; + + + case ACPI_DESC_TYPE_NAMED: + + AcpiDmDecodeNode ((ACPI_NAMESPACE_NODE *) ObjDesc); + break; + + + case ACPI_DESC_TYPE_OPERAND: + + Type = ObjDesc->Common.Type; + if (Type > ACPI_TYPE_LOCAL_MAX) + { + AcpiOsPrintf (" Type %X [Invalid Type]", (UINT32) Type); + return; + } + + /* Decode the ACPI object type */ + + switch (ObjDesc->Common.Type) + { + case ACPI_TYPE_LOCAL_REFERENCE: + + AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc)); + + /* Decode the refererence */ + + switch (ObjDesc->Reference.Class) + { + case ACPI_REFCLASS_LOCAL: + + AcpiOsPrintf ("%X ", ObjDesc->Reference.Value); + if (WalkState) + { + ObjDesc = WalkState->LocalVariables + [ObjDesc->Reference.Value].Object; + AcpiOsPrintf ("%p", ObjDesc); + AcpiDmDecodeInternalObject (ObjDesc); + } + break; + + + case ACPI_REFCLASS_ARG: + + AcpiOsPrintf ("%X ", ObjDesc->Reference.Value); + if (WalkState) + { + ObjDesc = WalkState->Arguments + [ObjDesc->Reference.Value].Object; + AcpiOsPrintf ("%p", ObjDesc); + AcpiDmDecodeInternalObject (ObjDesc); + } + break; + + + case ACPI_REFCLASS_INDEX: + + switch (ObjDesc->Reference.TargetType) + { + case ACPI_TYPE_BUFFER_FIELD: + + AcpiOsPrintf ("%p", ObjDesc->Reference.Object); + AcpiDmDecodeInternalObject (ObjDesc->Reference.Object); + break; + + case ACPI_TYPE_PACKAGE: + + AcpiOsPrintf ("%p", ObjDesc->Reference.Where); + if (!ObjDesc->Reference.Where) + { + AcpiOsPrintf (" Uninitialized WHERE pointer"); + } + else + { + AcpiDmDecodeInternalObject ( + *(ObjDesc->Reference.Where)); + } + break; + + default: + + AcpiOsPrintf ("Unknown index target type"); + break; + } + break; + + + case ACPI_REFCLASS_REFOF: + + if (!ObjDesc->Reference.Object) + { + AcpiOsPrintf ("Uninitialized reference subobject pointer"); + break; + } + + /* Reference can be to a Node or an Operand object */ + + switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc->Reference.Object)) + { + case ACPI_DESC_TYPE_NAMED: + AcpiDmDecodeNode (ObjDesc->Reference.Object); + break; + + case ACPI_DESC_TYPE_OPERAND: + AcpiDmDecodeInternalObject (ObjDesc->Reference.Object); + break; + + default: + break; + } + break; + + + case ACPI_REFCLASS_NAME: + + AcpiDmDecodeNode (ObjDesc->Reference.Node); + break; + + + case ACPI_REFCLASS_DEBUG: + case ACPI_REFCLASS_TABLE: + + AcpiOsPrintf ("\n"); + break; + + + default: /* Unknown reference class */ + + AcpiOsPrintf ("%2.2X\n", ObjDesc->Reference.Class); + break; + } + break; + + + default: + + AcpiOsPrintf ("<Obj> "); + AcpiDmDecodeInternalObject (ObjDesc); + break; + } + break; + + + default: + + AcpiOsPrintf ("<Not a valid ACPI Object Descriptor> [%s]", + AcpiUtGetDescriptorName (ObjDesc)); + break; + } + + AcpiOsPrintf ("\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDisplayLocals + * + * PARAMETERS: WalkState - State for current method + * + * RETURN: None + * + * DESCRIPTION: Display all locals for the currently running control method + * + ******************************************************************************/ + +void +AcpiDmDisplayLocals ( + ACPI_WALK_STATE *WalkState) +{ + UINT32 i; + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_NAMESPACE_NODE *Node; + + + ObjDesc = WalkState->MethodDesc; + Node = WalkState->MethodNode; + if (!Node) + { + AcpiOsPrintf ( + "No method node (Executing subtree for buffer or opregion)\n"); + return; + } + + if (Node->Type != ACPI_TYPE_METHOD) + { + AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); + return; + } + + AcpiOsPrintf ("Local Variables for method [%4.4s]:\n", + AcpiUtGetNodeName (Node)); + + for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) + { + ObjDesc = WalkState->LocalVariables[i].Object; + AcpiOsPrintf (" Local%X: ", i); + AcpiDmDisplayInternalObject (ObjDesc, WalkState); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDisplayArguments + * + * PARAMETERS: WalkState - State for current method + * + * RETURN: None + * + * DESCRIPTION: Display all arguments for the currently running control method + * + ******************************************************************************/ + +void +AcpiDmDisplayArguments ( + ACPI_WALK_STATE *WalkState) +{ + UINT32 i; + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_NAMESPACE_NODE *Node; + + + ObjDesc = WalkState->MethodDesc; + Node = WalkState->MethodNode; + if (!Node) + { + AcpiOsPrintf ( + "No method node (Executing subtree for buffer or opregion)\n"); + return; + } + + if (Node->Type != ACPI_TYPE_METHOD) + { + AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n"); + return; + } + + AcpiOsPrintf ( + "Arguments for Method [%4.4s]: (%X arguments defined, max concurrency = %X)\n", + AcpiUtGetNodeName (Node), ObjDesc->Method.ParamCount, ObjDesc->Method.SyncLevel); + + for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) + { + ObjDesc = WalkState->Arguments[i].Object; + AcpiOsPrintf (" Arg%u: ", i); + AcpiDmDisplayInternalObject (ObjDesc, WalkState); + } +} + +#endif + + diff --git a/source/components/disassembler/dmopcode.c b/source/components/disassembler/dmopcode.c new file mode 100644 index 0000000..6d2c3e1 --- /dev/null +++ b/source/components/disassembler/dmopcode.c @@ -0,0 +1,607 @@ +/******************************************************************************* + * + * Module Name: dmopcode - AML disassembler, specific AML opcodes + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdisasm.h" + +#ifdef ACPI_DISASSEMBLER + +#define _COMPONENT ACPI_CA_DEBUGGER + ACPI_MODULE_NAME ("dmopcode") + +/* Local prototypes */ + +static void +AcpiDmMatchKeyword ( + ACPI_PARSE_OBJECT *Op); + + +/******************************************************************************* + * + * 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", ACPI_CAST_PTR (char, + 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; + + + if (!Op) + { + AcpiOsPrintf ("<NULL OP PTR>"); + return; + } + + switch (Op->Common.DisasmOpcode) + { + case ACPI_DASM_MATCHOP: + + AcpiDmMatchKeyword (Op); + return; + + case ACPI_DASM_LNOT_SUFFIX: + 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) + { + AcpiDmEisaId ((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) + { + AcpiDmEisaId ((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_UINT8_MAX); + 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 (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 (AcpiDmIsUnicodeBuffer (Op)) + { + Op->Common.DisasmOpcode = ACPI_DASM_UNICODE; + AcpiOsPrintf ("Unicode ("); + } + else if (AcpiDmIsStringBuffer (Op)) + { + Op->Common.DisasmOpcode = ACPI_DASM_STRING; + AcpiOsPrintf ("Buffer"); + } + else + { + Op->Common.DisasmOpcode = ACPI_DASM_BUFFER; + AcpiOsPrintf ("Buffer"); + } + break; + + + case AML_INT_STATICSTRING_OP: + + if (Op->Common.Value.String) + { + AcpiOsPrintf ("%s", Op->Common.Value.String); + } + else + { + AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\""); + } + 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; + 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; + + + 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)) + { + AcpiDmDecodeInternalObject ( + WalkState->Results->Results.ObjDesc [ + (WalkState->ResultCount - 1) % + ACPI_RESULTS_FRAME_OBJ_NUM]); + } +#endif + + break; + } +} + +#endif /* ACPI_DISASSEMBLER */ diff --git a/source/components/disassembler/dmresrc.c b/source/components/disassembler/dmresrc.c new file mode 100644 index 0000000..9c07bf7 --- /dev/null +++ b/source/components/disassembler/dmresrc.c @@ -0,0 +1,434 @@ +/******************************************************************************* + * + * Module Name: dmresrc.c - Resource Descriptor disassembly + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, 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_DISASSEMBLER + +#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, + char *Name) +{ + AcpiOsPrintf ("0x%2.2X, // %s\n", Value, Name); +} + +void +AcpiDmDumpInteger16 ( + UINT16 Value, + char *Name) +{ + AcpiOsPrintf ("0x%4.4X, // %s\n", Value, Name); +} + +void +AcpiDmDumpInteger32 ( + UINT32 Value, + char *Name) +{ + AcpiOsPrintf ("0x%8.8X, // %s\n", Value, Name); +} + +void +AcpiDmDumpInteger64 ( + UINT64 Value, + 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; + + + 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 (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 (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] ( + Aml, ResourceLength, Level); + + /* Descriptor post-processing */ + + if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT) + { + DependentFns = TRUE; + Level++; + } + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmIsResourceTemplate + * + * PARAMETERS: 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_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; + 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 (Aml, Length, NULL, &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); +} + +#endif diff --git a/source/components/disassembler/dmresrcl.c b/source/components/disassembler/dmresrcl.c new file mode 100644 index 0000000..ed78b31 --- /dev/null +++ b/source/components/disassembler/dmresrcl.c @@ -0,0 +1,1052 @@ +/******************************************************************************* + * + * Module Name: dmresrcl.c - "Large" Resource Descriptor disassembly + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, 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" + + +#ifdef ACPI_DISASSEMBLER + +#define _COMPONENT ACPI_CA_DEBUGGER + ACPI_MODULE_NAME ("dbresrcl") + + +/* Common names for address and memory descriptors */ + +static char *AcpiDmAddressNames[] = +{ + "Granularity", + "Range Minimum", + "Range Maximum", + "Translation Offset", + "Length" +}; + +static 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 [ResourceType & 0x3]); + + /* 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 [SpecificFlags & 0x3]); + } + } +} + + +/******************************************************************************* + * + * 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 [(Flags & 1)], + AcpiGbl_DecDecode [(Flags & 0x2) >> 1], + AcpiGbl_MinDecode [(Flags & 0x4) >> 2], + AcpiGbl_MaxDecode [(Flags & 0x8) >> 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 [(Flags & 1)], + AcpiGbl_MinDecode [(Flags & 0x4) >> 2], + AcpiGbl_MaxDecode [(Flags & 0x8) >> 3], + AcpiGbl_DecDecode [(Flags & 0x2) >> 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 [(SpecificFlags & 0x10) >> 4]); + + /* TRS is only used if TTP is TypeTranslation */ + + if (SpecificFlags & 0x10) + { + AcpiOsPrintf (", %s", + AcpiGbl_TrsDecode [(SpecificFlags & 0x20) >> 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 [(Flags & 1)], + AcpiGbl_DecDecode [(Flags & 0x2) >> 1], + AcpiGbl_MinDecode [(Flags & 0x4) >> 2], + AcpiGbl_MaxDecode [(Flags & 0x8) >> 3], + AcpiGbl_MemDecode [(SpecificFlags & 0x6) >> 1], + AcpiGbl_RwDecode [(SpecificFlags & 0x1)]); +} + + +/******************************************************************************* + * + * 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 [(SpecificFlags & 0x18) >> 3], + AcpiGbl_TtpDecode [(SpecificFlags & 0x20) >> 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_UINT8_MAX); + } + + AcpiOsPrintf (", "); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmWordDescriptor + * + * PARAMETERS: 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 ( + 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: 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 ( + 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: 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 ( + 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: 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 ( + 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: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + /* Dump name and read/write flag */ + + AcpiDmIndent (Level); + AcpiOsPrintf ("Memory24 (%s,\n", + AcpiGbl_RwDecode [Resource->Memory24.Flags & 1]); + + /* 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: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + /* Dump name and read/write flag */ + + AcpiDmIndent (Level); + AcpiOsPrintf ("Memory32 (%s,\n", + AcpiGbl_RwDecode [Resource->Memory32.Flags & 1]); + + /* 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: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + /* Dump name and read/write flag */ + + AcpiDmIndent (Level); + AcpiOsPrintf ("Memory32Fixed (%s,\n", + AcpiGbl_RwDecode [Resource->FixedMemory32.Flags & 1]); + + 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: 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 ( + 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: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + UINT32 i; + + + AcpiDmIndent (Level); + AcpiOsPrintf ("Interrupt (%s, %s, %s, %s, ", + AcpiGbl_ConsumeDecode [(Resource->ExtendedIrq.Flags & 1)], + AcpiGbl_HeDecode [(Resource->ExtendedIrq.Flags >> 1) & 1], + AcpiGbl_LlDecode [(Resource->ExtendedIrq.Flags >> 2) & 1], + AcpiGbl_ShrDecode [(Resource->ExtendedIrq.Flags >> 3) & 1]); + + /* + * 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 ( + 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: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + AcpiDmVendorCommon ("Long ", + ACPI_ADD_PTR (UINT8, Resource, sizeof (AML_RESOURCE_LARGE_HEADER)), + Length, Level); +} + +#endif diff --git a/source/components/disassembler/dmresrcl2.c b/source/components/disassembler/dmresrcl2.c new file mode 100644 index 0000000..e79307e --- /dev/null +++ b/source/components/disassembler/dmresrcl2.c @@ -0,0 +1,700 @@ +/******************************************************************************* + * + * Module Name: dmresrcl2.c - "Large" Resource Descriptor disassembly (#2) + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, 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" + + +#ifdef ACPI_DISASSEMBLER + +#define _COMPONENT ACPI_CA_DEBUGGER + ACPI_MODULE_NAME ("dbresrcl2") + +/* Local prototypes */ + +static void +AcpiDmI2cSerialBusDescriptor ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level); + +static void +AcpiDmSpiSerialBusDescriptor ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level); + +static void +AcpiDmUartSerialBusDescriptor ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level); + +static void +AcpiDmGpioCommon ( + 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: 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 ( + AML_RESOURCE *Resource, + UINT32 Level) +{ + UINT32 PinCount; + UINT16 *PinList; + UINT8 *VendorData; + UINT32 i; + + + /* ResourceSource, ResourceSourceIndex, ResourceType */ + + AcpiDmIndent (Level + 1); + if (Resource->Gpio.ResSourceOffset) + { + AcpiUtPrintString ( + ACPI_ADD_PTR (char, Resource, Resource->Gpio.ResSourceOffset), + ACPI_UINT8_MAX); + } + + AcpiOsPrintf (", "); + AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.ResSourceIndex); + AcpiOsPrintf ("%s, ", + AcpiGbl_ConsumeDecode [(Resource->Gpio.Flags & 1)]); + + /* 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"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGpioIntDescriptor + * + * PARAMETERS: 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 ( + 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 [(Resource->Gpio.IntFlags & 1)], + AcpiGbl_LlDecode [(Resource->Gpio.IntFlags >> 1) & 1], + AcpiGbl_ShrDecode [(Resource->Gpio.IntFlags >> 3) & 1]); + + /* 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 (Resource, Level); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGpioIoDescriptor + * + * PARAMETERS: 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 +AcpiDmGpioIoDescriptor ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + /* Dump the GpioIo-specific portion of the descriptor */ + + /* Shared, PinConfig */ + + AcpiDmIndent (Level); + AcpiOsPrintf ("GpioIo (%s, ", + AcpiGbl_ShrDecode [(Resource->Gpio.IntFlags >> 3) & 1]); + + 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 [Resource->Gpio.IntFlags & 3]); + + /* Dump the GpioInt/GpioIo common portion of the descriptor */ + + AcpiDmGpioCommon (Resource, Level); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGpioDescriptor + * + * PARAMETERS: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + UINT8 ConnectionType; + + + ConnectionType = Resource->Gpio.ConnectionType; + + switch (ConnectionType) + { + case AML_RESOURCE_GPIO_TYPE_INT: + AcpiDmGpioIntDescriptor (Resource, Length, Level); + break; + + case AML_RESOURCE_GPIO_TYPE_IO: + AcpiDmGpioIoDescriptor (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: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + UINT32 ResourceSourceOffset; + + + /* SlaveAddress, SlaveMode, ConnectionSpeed, AddressingMode */ + + AcpiDmIndent (Level); + AcpiOsPrintf ("I2cSerialBus (0x%4.4X, %s, 0x%8.8X,\n", + Resource->I2cSerialBus.SlaveAddress, + AcpiGbl_SmDecode [(Resource->I2cSerialBus.Flags & 1)], + Resource->I2cSerialBus.ConnectionSpeed); + + AcpiDmIndent (Level + 1); + AcpiOsPrintf ("%s, ", + AcpiGbl_AmDecode [(Resource->I2cSerialBus.TypeSpecificFlags & 1)]); + + /* ResourceSource is a required field */ + + ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) + + Resource->CommonSerialBus.TypeDataLength; + + AcpiUtPrintString ( + ACPI_ADD_PTR (char, Resource, ResourceSourceOffset), + ACPI_UINT8_MAX); + + /* ResourceSourceIndex, ResourceUsage */ + + AcpiOsPrintf (",\n"); + AcpiDmIndent (Level + 1); + AcpiOsPrintf ("0x%2.2X, ", Resource->I2cSerialBus.ResSourceIndex); + + AcpiOsPrintf ("%s, ", + AcpiGbl_ConsumeDecode [(Resource->I2cSerialBus.Flags >> 1) & 1]); + + /* Insert a descriptor name */ + + AcpiDmDescriptorName (); + AcpiOsPrintf (",\n"); + + /* Dump the vendor data */ + + AcpiDmIndent (Level + 1); + AcpiDmDumpSerialBusVendorData (Resource, Level); + AcpiOsPrintf (")\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmSpiSerialBusDescriptor + * + * PARAMETERS: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + UINT32 ResourceSourceOffset; + + + /* DeviceSelection, DeviceSelectionPolarity, WireMode, DataBitLength */ + + AcpiDmIndent (Level); + AcpiOsPrintf ("SpiSerialBus (0x%4.4X, %s, %s, 0x%2.2X,\n", + Resource->SpiSerialBus.DeviceSelection, + AcpiGbl_DpDecode [(Resource->SpiSerialBus.TypeSpecificFlags >> 1) & 1], + AcpiGbl_WmDecode [(Resource->SpiSerialBus.TypeSpecificFlags & 1)], + Resource->SpiSerialBus.DataBitLength); + + /* SlaveMode, ConnectionSpeed, ClockPolarity, ClockPhase */ + + AcpiDmIndent (Level + 1); + AcpiOsPrintf ("%s, 0x%8.8X, %s,\n", + AcpiGbl_SmDecode [(Resource->SpiSerialBus.Flags & 1)], + Resource->SpiSerialBus.ConnectionSpeed, + AcpiGbl_CpoDecode [(Resource->SpiSerialBus.ClockPolarity & 1)]); + + AcpiDmIndent (Level + 1); + AcpiOsPrintf ("%s, ", + AcpiGbl_CphDecode [(Resource->SpiSerialBus.ClockPhase & 1)]); + + /* ResourceSource is a required field */ + + ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) + + Resource->CommonSerialBus.TypeDataLength; + + AcpiUtPrintString ( + ACPI_ADD_PTR (char, Resource, ResourceSourceOffset), + ACPI_UINT8_MAX); + + /* ResourceSourceIndex, ResourceUsage */ + + AcpiOsPrintf (",\n"); + AcpiDmIndent (Level + 1); + AcpiOsPrintf ("0x%2.2X, ", Resource->SpiSerialBus.ResSourceIndex); + + AcpiOsPrintf ("%s, ", + AcpiGbl_ConsumeDecode [(Resource->SpiSerialBus.Flags >> 1) & 1]); + + /* Insert a descriptor name */ + + AcpiDmDescriptorName (); + AcpiOsPrintf (",\n"); + + /* Dump the vendor data */ + + AcpiDmIndent (Level + 1); + AcpiDmDumpSerialBusVendorData (Resource, Level); + AcpiOsPrintf (")\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmUartSerialBusDescriptor + * + * PARAMETERS: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + UINT32 ResourceSourceOffset; + + + /* ConnectionSpeed, BitsPerByte, StopBits */ + + AcpiDmIndent (Level); + AcpiOsPrintf ("UartSerialBus (0x%8.8X, %s, %s,\n", + Resource->UartSerialBus.DefaultBaudRate, + AcpiGbl_BpbDecode [(Resource->UartSerialBus.TypeSpecificFlags >> 4) & 3], + AcpiGbl_SbDecode [(Resource->UartSerialBus.TypeSpecificFlags >> 2) & 3]); + + /* LinesInUse, IsBigEndian, Parity, FlowControl */ + + AcpiDmIndent (Level + 1); + AcpiOsPrintf ("0x%2.2X, %s, %s, %s,\n", + Resource->UartSerialBus.LinesEnabled, + AcpiGbl_EdDecode [(Resource->UartSerialBus.TypeSpecificFlags >> 7) & 1], + AcpiGbl_PtDecode [Resource->UartSerialBus.Parity & 7], + AcpiGbl_FcDecode [Resource->UartSerialBus.TypeSpecificFlags & 3]); + + /* 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; + + AcpiUtPrintString ( + ACPI_ADD_PTR (char, Resource, ResourceSourceOffset), + ACPI_UINT8_MAX); + + /* ResourceSourceIndex, ResourceUsage */ + + AcpiOsPrintf (",\n"); + AcpiDmIndent (Level + 1); + AcpiOsPrintf ("0x%2.2X, ", Resource->UartSerialBus.ResSourceIndex); + + AcpiOsPrintf ("%s, ", + AcpiGbl_ConsumeDecode [(Resource->UartSerialBus.Flags >> 1) & 1]); + + /* Insert a descriptor name */ + + AcpiDmDescriptorName (); + AcpiOsPrintf (",\n"); + + /* Dump the vendor data */ + + AcpiDmIndent (Level + 1); + AcpiDmDumpSerialBusVendorData (Resource, Level); + AcpiOsPrintf (")\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmSerialBusDescriptor + * + * PARAMETERS: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + SerialBusResourceDispatch [Resource->CommonSerialBus.Type] ( + Resource, Length, Level); +} + +#endif + diff --git a/source/components/disassembler/dmresrcs.c b/source/components/disassembler/dmresrcs.c new file mode 100644 index 0000000..32759d9 --- /dev/null +++ b/source/components/disassembler/dmresrcs.c @@ -0,0 +1,358 @@ +/******************************************************************************* + * + * Module Name: dmresrcs.c - "Small" Resource Descriptor disassembly + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, 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" + + +#ifdef ACPI_DISASSEMBLER + +#define _COMPONENT ACPI_CA_DEBUGGER + ACPI_MODULE_NAME ("dbresrcs") + + +/******************************************************************************* + * + * FUNCTION: AcpiDmIrqDescriptor + * + * PARAMETERS: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + AcpiDmIndent (Level); + AcpiOsPrintf ("%s (", + AcpiGbl_IrqDecode [Length & 1]); + + /* Decode flags byte if present */ + + if (Length & 1) + { + AcpiOsPrintf ("%s, %s, %s, ", + AcpiGbl_HeDecode [Resource->Irq.Flags & 1], + AcpiGbl_LlDecode [(Resource->Irq.Flags >> 3) & 1], + AcpiGbl_ShrDecode [(Resource->Irq.Flags >> 4) & 1]); + } + + /* Insert a descriptor name */ + + AcpiDmDescriptorName (); + AcpiOsPrintf (")\n"); + + AcpiDmIndent (Level + 1); + AcpiDmBitList (Resource->Irq.IrqMask); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDmaDescriptor + * + * PARAMETERS: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + AcpiDmIndent (Level); + AcpiOsPrintf ("DMA (%s, %s, %s, ", + AcpiGbl_TypDecode [(Resource->Dma.Flags >> 5) & 3], + AcpiGbl_BmDecode [(Resource->Dma.Flags >> 2) & 1], + AcpiGbl_SizDecode [(Resource->Dma.Flags >> 0) & 3]); + + /* Insert a descriptor name */ + + AcpiDmDescriptorName (); + AcpiOsPrintf (")\n"); + + AcpiDmIndent (Level + 1); + AcpiDmBitList (Resource->Dma.DmaChannelMask); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmFixedDmaDescriptor + * + * PARAMETERS: 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 ( + 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: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + AcpiDmIndent (Level); + AcpiOsPrintf ("IO (%s,\n", + AcpiGbl_IoDecode [(Resource->Io.Flags & 1)]); + + 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: 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 ( + 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: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + AcpiDmIndent (Level); + + if (Length & 1) + { + AcpiOsPrintf ("StartDependentFn (0x%2.2X, 0x%2.2X)\n", + (UINT32) Resource->StartDpf.Flags & 3, + (UINT32) (Resource->StartDpf.Flags >> 2) & 3); + } + else + { + AcpiOsPrintf ("StartDependentFnNoPri ()\n"); + } + + AcpiDmIndent (Level); + AcpiOsPrintf ("{\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmEndDependentDescriptor + * + * PARAMETERS: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + AcpiDmIndent (Level); + AcpiOsPrintf ("}\n"); + AcpiDmIndent (Level); + AcpiOsPrintf ("EndDependentFn ()\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmVendorSmallDescriptor + * + * PARAMETERS: 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 ( + AML_RESOURCE *Resource, + UINT32 Length, + UINT32 Level) +{ + + AcpiDmVendorCommon ("Short", + ACPI_ADD_PTR (UINT8, Resource, sizeof (AML_RESOURCE_SMALL_HEADER)), + Length, Level); +} + +#endif + diff --git a/source/components/disassembler/dmutils.c b/source/components/disassembler/dmutils.c new file mode 100644 index 0000000..ce3443e --- /dev/null +++ b/source/components/disassembler/dmutils.c @@ -0,0 +1,321 @@ +/******************************************************************************* + * + * Module Name: dmutils - AML disassembler utilities + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, 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 + +#ifdef ACPI_DISASSEMBLER + +#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", ACPI_MUL_4 (Level), " "); +} + + +/******************************************************************************* + * + * 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) + { + /* 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_PARAMLIST) && + (!(Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))) + { + return FALSE; + } + + AcpiOsPrintf (", "); + return (TRUE); + } + + else if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) && + (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) + { + 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 (", "); + } +} + +#endif diff --git a/source/components/disassembler/dmwalk.c b/source/components/disassembler/dmwalk.c new file mode 100644 index 0000000..dd3ee00 --- /dev/null +++ b/source/components/disassembler/dmwalk.c @@ -0,0 +1,935 @@ +/******************************************************************************* + * + * Module Name: dmwalk - AML disassembly tree walk + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include "acpi.h" +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdisasm.h" +#include "acdebug.h" + + +#ifdef ACPI_DISASSEMBLER + +#define _COMPONENT ACPI_CA_DEBUGGER + ACPI_MODULE_NAME ("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; + } + + Info.Flags = 0; + Info.Level = 0; + Info.Count = 0; + Info.WalkState = WalkState; + 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) + { + 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); + + 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; + + + if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) + { + /* Ignore this op -- it was handled elsewhere */ + + 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) + { + VERBOSE_PRINT ((DB_FULL_OP_INFO, + (Info->WalkState->MethodNode ? + Info->WalkState->MethodNode->Name.Ascii : " "), + Op->Common.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_PARAMLIST)) && + (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) + { + /* + * This is a first-level element of a term list, + * indent a new line + */ + AcpiDmIndent (Level); + 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*/ > 10) + { + Info->Count = 0; + AcpiOsPrintf ("\n"); + AcpiDmIndent (Info->LastLevel + 1); + } + + /* 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 */ + + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + + 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_DbOpt_verbose) + { + (void) AcpiPsDisplayObjectPathname (NULL, Op); + } + } + break; + } + + switch (Op->Common.AmlOpcode) + { + case AML_METHOD_OP: + + AcpiDmMethodFlags (Op); + AcpiOsPrintf (")"); + break; + + + case AML_NAME_OP: + + /* Check for _HID and related EISAID() */ + + AcpiDmIsEisaId (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_PARAMLIST; + + NextOp = NextOp->Common.Next; + NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; + 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_PARAMLIST; + + NextOp = NextOp->Common.Next; + NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; + + NextOp = NextOp->Common.Next; + NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; + return (AE_OK); + + + case AML_MUTEX_OP: + case AML_DATA_REGION_OP: + + AcpiOsPrintf (", "); + return (AE_OK); + + + case AML_EVENT_OP: + case AML_ALIAS_OP: + + return (AE_OK); + + + case AML_SCOPE_OP: + case AML_DEVICE_OP: + case AML_THERMAL_ZONE_OP: + + 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_PARAMLIST + * eliminates newline in the output. + */ + NextOp = NextOp->Common.Next; + + Info->Flags = ACPI_PARSEOP_PARAMLIST; + 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 (")\n"); + AcpiDmIndent (Info->Level); + AcpiOsPrintf ("{\n"); + return (AE_OK); + } + + /* Normal Buffer, mark size as in the parameter list */ + + NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; + return (AE_OK); + + + case AML_VAR_PACKAGE_OP: + case AML_IF_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_PARAMLIST; + } + return (AE_OK); + + + case AML_PACKAGE_OP: + + /* The next op is the size or predicate parameter */ + + NextOp = AcpiPsGetDepthNext (NULL, Op); + if (NextOp) + { + NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; + } + 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; + + + 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 */ + + AcpiOsPrintf (")"); + + /* Could be a nested operator, check if comma required */ + + if (!AcpiDmCommaIfListMember (Op)) + { + if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && + (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && + (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_PARAMLIST)) + { + 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_PARAMLIST)) && + (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_PARAMLIST)) + { + AcpiOsPrintf ("\n"); + } + break; + + default: + + break; + } + } + break; + } + + if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) + { + if ((Op->Common.Next) && + (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) + { + return (AE_OK); + } + + /* + * 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 (")\n"); + AcpiDmIndent (Level - 1); + AcpiOsPrintf ("{\n"); + } + else + { + Op->Common.Parent->Common.DisasmFlags |= + ACPI_PARSEOP_EMPTY_TERMLIST; + AcpiOsPrintf (") {"); + } + } + + if ((Op->Common.AmlOpcode == AML_NAME_OP) || + (Op->Common.AmlOpcode == AML_RETURN_OP)) + { + Info->Level++; + } + return (AE_OK); +} + + +#endif /* ACPI_DISASSEMBLER */ |