diff options
Diffstat (limited to 'source/components/disassembler')
-rw-r--r-- | source/components/disassembler/dmbuffer.c | 114 | ||||
-rw-r--r-- | source/components/disassembler/dmopcode.c | 195 | ||||
-rw-r--r-- | source/components/disassembler/dmwalk.c | 11 |
3 files changed, 251 insertions, 69 deletions
diff --git a/source/components/disassembler/dmbuffer.c b/source/components/disassembler/dmbuffer.c index ce69459..85f0618 100644 --- a/source/components/disassembler/dmbuffer.c +++ b/source/components/disassembler/dmbuffer.c @@ -47,6 +47,7 @@ #include "acdisasm.h" #include "acparser.h" #include "amlcode.h" +#include "acinterp.h" #ifdef ACPI_DISASSEMBLER @@ -61,7 +62,7 @@ AcpiDmUnicode ( ACPI_PARSE_OBJECT *Op); static void -AcpiDmIsEisaIdElement ( +AcpiDmGetHardwareIdType ( ACPI_PARSE_OBJECT *Op); static void @@ -537,19 +538,20 @@ AcpiDmUnicode ( /******************************************************************************* * - * FUNCTION: AcpiDmIsEisaIdElement + * FUNCTION: AcpiDmGetHardwareIdType * * 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. + * DESCRIPTION: Determine the type of the argument to a _HID or _CID + * 1) Strings are allowed + * 2) If Integer, determine if it is a valid EISAID * ******************************************************************************/ static void -AcpiDmIsEisaIdElement ( +AcpiDmGetHardwareIdType ( ACPI_PARSE_OBJECT *Op) { UINT32 BigEndianId; @@ -557,55 +559,66 @@ AcpiDmIsEisaIdElement ( 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)) + switch (Op->Common.AmlOpcode) { - return; - } + case AML_STRING_OP: - /* Swap from little-endian to big-endian to simplify conversion */ + /* Mark this string as an _HID/_CID string */ - BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer); + Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING; + break; - /* Create the 3 leading ASCII letters */ + case AML_WORD_OP: + case AML_DWORD_OP: - Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40; - Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40; - Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40; + /* Determine if a Word/Dword is a valid encoded EISAID */ - /* Verify that all 3 are ascii and alpha */ + /* Swap from little-endian to big-endian to simplify conversion */ - for (i = 0; i < 3; i++) - { - if (!ACPI_IS_ASCII (Prefix[i]) || - !ACPI_IS_ALPHA (Prefix[i])) + 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++) { - return; + if (!ACPI_IS_ASCII (Prefix[i]) || + !ACPI_IS_ALPHA (Prefix[i])) + { + return; + } } - } - /* OK - mark this node as convertable to an EISA ID */ + /* Mark this node as convertable to an EISA ID string */ - Op->Common.DisasmOpcode = ACPI_DASM_EISAID; + Op->Common.DisasmOpcode = ACPI_DASM_EISAID; + break; + + default: + break; + } } /******************************************************************************* * - * FUNCTION: AcpiDmIsEisaId + * FUNCTION: AcpiDmCheckForHardwareId * * PARAMETERS: Op - Op to be examined * * RETURN: None * - * DESCRIPTION: Determine if a Name() Op can be converted to an EisaId. + * DESCRIPTION: Determine if a Name() Op is a _HID/_CID. * ******************************************************************************/ void -AcpiDmIsEisaId ( +AcpiDmCheckForHardwareId ( ACPI_PARSE_OBJECT *Op) { UINT32 Name; @@ -630,7 +643,7 @@ AcpiDmIsEisaId ( if (ACPI_COMPARE_NAME (&Name, METHOD_NAME__HID)) { - AcpiDmIsEisaIdElement (NextOp); + AcpiDmGetHardwareIdType (NextOp); return; } @@ -645,11 +658,11 @@ AcpiDmIsEisaId ( if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP) { - AcpiDmIsEisaIdElement (NextOp); + AcpiDmGetHardwareIdType (NextOp); return; } - /* _CID with Package: get the package length */ + /* _CID with Package: get the package length, check all elements */ NextOp = AcpiPsGetDepthNext (NULL, NextOp); @@ -658,7 +671,7 @@ AcpiDmIsEisaId ( NextOp = NextOp->Common.Next; while (NextOp) { - AcpiDmIsEisaIdElement (NextOp); + AcpiDmGetHardwareIdType (NextOp); NextOp = NextOp->Common.Next; } } @@ -666,41 +679,38 @@ AcpiDmIsEisaId ( /******************************************************************************* * - * FUNCTION: AcpiDmEisaId + * FUNCTION: AcpiDmDecompressEisaId * * PARAMETERS: EncodedId - Raw encoded EISA ID. * * RETURN: None * - * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String. + * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String + * and emit the correct ASL statement. If the ID is known, emit + * a description of the ID as a comment. * ******************************************************************************/ void -AcpiDmEisaId ( +AcpiDmDecompressEisaId ( UINT32 EncodedId) { - UINT32 BigEndianId; - + char IdBuffer[ACPI_EISAID_STRING_SIZE]; + const AH_DEVICE_ID *Info; - /* Swap from little-endian to big-endian to simplify conversion */ - BigEndianId = AcpiUtDwordByteSwap (EncodedId); + /* Convert EISAID to a string an emit the statement */ + AcpiExEisaIdToString (IdBuffer, EncodedId); + AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer); - /* Split to form "AAANNNN" string */ + /* If we know about the ID, emit the description */ - 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)); + Info = AcpiAhMatchHardwareId (IdBuffer); + if (Info) + { + AcpiOsPrintf (" /* %s */", Info->Description); + } } #endif diff --git a/source/components/disassembler/dmopcode.c b/source/components/disassembler/dmopcode.c index 10c66b2..30f985c 100644 --- a/source/components/disassembler/dmopcode.c +++ b/source/components/disassembler/dmopcode.c @@ -46,6 +46,8 @@ #include "acparser.h" #include "amlcode.h" #include "acdisasm.h" +#include "acinterp.h" +#include "acnamesp.h" #ifdef ACPI_DISASSEMBLER @@ -61,6 +63,159 @@ AcpiDmMatchKeyword ( /******************************************************************************* * + * FUNCTION: AcpiDmDisplayTargetPathname + * + * PARAMETERS: Op - Parse object + * + * RETURN: None + * + * DESCRIPTION: For AML opcodes that have a target operand, display the full + * pathname for the target, in a comment field. Handles Return() + * statements also. + * + ******************************************************************************/ + +void +AcpiDmDisplayTargetPathname ( + ACPI_PARSE_OBJECT *Op) +{ + ACPI_PARSE_OBJECT *NextOp; + ACPI_PARSE_OBJECT *PrevOp = NULL; + char *Pathname; + const ACPI_OPCODE_INFO *OpInfo; + + + if (Op->Common.AmlOpcode == AML_RETURN_OP) + { + PrevOp = Op->Asl.Value.Arg; + } + else + { + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + if (!(OpInfo->Flags & AML_HAS_TARGET)) + { + return; + } + + /* Target is the last Op in the arg list */ + + NextOp = Op->Asl.Value.Arg; + while (NextOp) + { + PrevOp = NextOp; + NextOp = PrevOp->Asl.Next; + } + } + + if (!PrevOp) + { + return; + } + + /* We must have a namepath AML opcode */ + + if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) + { + return; + } + + /* A null string is the "no target specified" case */ + + if (!PrevOp->Asl.Value.String) + { + return; + } + + /* No node means "unresolved external reference" */ + + if (!PrevOp->Asl.Node) + { + AcpiOsPrintf (" /* External reference */"); + return; + } + + /* Ignore if path is already from the root */ + + if (*PrevOp->Asl.Value.String == '\\') + { + return; + } + + /* Now: we can get the full pathname */ + + Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node); + if (!Pathname) + { + return; + } + + AcpiOsPrintf (" /* %s */", Pathname); + ACPI_FREE (Pathname); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmNotifyDescription + * + * PARAMETERS: Op - Name() parse object + * + * RETURN: None + * + * DESCRIPTION: Emit a description comment for the value associated with a + * Notify() operator. + * + ******************************************************************************/ + +void +AcpiDmNotifyDescription ( + ACPI_PARSE_OBJECT *Op) +{ + ACPI_PARSE_OBJECT *NextOp; + ACPI_NAMESPACE_NODE *Node; + UINT8 NotifyValue; + UINT8 Type = ACPI_TYPE_ANY; + + + /* The notify value is the second argument */ + + NextOp = Op->Asl.Value.Arg; + NextOp = NextOp->Asl.Next; + + switch (NextOp->Common.AmlOpcode) + { + case AML_ZERO_OP: + case AML_ONE_OP: + + NotifyValue = (UINT8) NextOp->Common.AmlOpcode; + break; + + case AML_BYTE_OP: + + NotifyValue = (UINT8) NextOp->Asl.Value.Integer; + break; + + default: + return; + } + + /* + * Attempt to get the namespace node so we can determine the object type. + * Some notify values are dependent on the object type (Device, Thermal, + * or Processor). + */ + Node = Op->Asl.Node; + if (Node) + { + Type = Node->Type; + } + + AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type)); +} + + +/******************************************************************************* + * * FUNCTION: AcpiDmPredefinedDescription * * PARAMETERS: Op - Name() parse object @@ -183,14 +338,11 @@ AcpiDmPredefinedDescription ( /* Match the name in the info table */ - for (Info = AslPredefinedInfo; Info->Name; Info++) + Info = AcpiAhMatchPredefinedName (NameString); + if (Info) { - if (ACPI_COMPARE_NAME (NameString, Info->Name)) - { - AcpiOsPrintf (" // %4.4s: %s", - NameString, ACPI_CAST_PTR (char, Info->Description)); - return; - } + AcpiOsPrintf (" // %4.4s: %s", + NameString, ACPI_CAST_PTR (char, Info->Description)); } #endif @@ -267,14 +419,11 @@ AcpiDmFieldPredefinedDescription ( /* Match the name in the info table */ - for (Info = AslPredefinedInfo; Info->Name; Info++) + Info = AcpiAhMatchPredefinedName (Tag); + if (Info) { - if (ACPI_COMPARE_NAME (Tag, Info->Name)) - { - AcpiOsPrintf (" // %4.4s: %s", Tag, - ACPI_CAST_PTR (char, Info->Description)); - return; - } + AcpiOsPrintf (" // %4.4s: %s", Tag, + ACPI_CAST_PTR (char, Info->Description)); } #endif @@ -527,6 +676,7 @@ AcpiDmDisassembleOneOp ( ACPI_PARSE_OBJECT *Child; ACPI_STATUS Status; UINT8 *Aml; + const AH_DEVICE_ID *IdInfo; if (!Op) @@ -605,7 +755,7 @@ AcpiDmDisassembleOneOp ( if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) { - AcpiDmEisaId ((UINT32) Op->Common.Value.Integer); + AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer); } else { @@ -617,7 +767,7 @@ AcpiDmDisassembleOneOp ( if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) { - AcpiDmEisaId ((UINT32) Op->Common.Value.Integer); + AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer); } else { @@ -634,6 +784,19 @@ AcpiDmDisassembleOneOp ( case AML_STRING_OP: AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX); + + /* For _HID/_CID strings, attempt to output a descriptive comment */ + + if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING) + { + /* If we know about the ID, emit the description */ + + IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String); + if (IdInfo) + { + AcpiOsPrintf (" /* %s */", IdInfo->Description); + } + } break; case AML_BUFFER_OP: diff --git a/source/components/disassembler/dmwalk.c b/source/components/disassembler/dmwalk.c index 79242f5..3cf74b3 100644 --- a/source/components/disassembler/dmwalk.c +++ b/source/components/disassembler/dmwalk.c @@ -568,7 +568,7 @@ AcpiDmDescendingOp ( /* Check for _HID and related EISAID() */ - AcpiDmIsEisaId (Op); + AcpiDmCheckForHardwareId (Op); AcpiOsPrintf (", "); break; @@ -842,6 +842,15 @@ AcpiDmAscendingOp ( AcpiDmFieldPredefinedDescription (Op); } + /* Decode Notify() values */ + + if (Op->Common.AmlOpcode == AML_NOTIFY_OP) + { + AcpiDmNotifyDescription (Op); + } + + AcpiDmDisplayTargetPathname (Op); + /* Could be a nested operator, check if comma required */ if (!AcpiDmCommaIfListMember (Op)) |