Home | History | Annotate | Line # | Download | only in disassembler
dmresrc.c revision 1.3.24.1
      1 /*******************************************************************************
      2  *
      3  * Module Name: dmresrc.c - Resource Descriptor disassembly
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2013, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 
     45 #include "acpi.h"
     46 #include "accommon.h"
     47 #include "amlcode.h"
     48 #include "acdisasm.h"
     49 
     50 #ifdef ACPI_DISASSEMBLER
     51 
     52 #define _COMPONENT          ACPI_CA_DEBUGGER
     53         ACPI_MODULE_NAME    ("dbresrc")
     54 
     55 
     56 /* Dispatch tables for Resource disassembly functions */
     57 
     58 static ACPI_RESOURCE_HANDLER    AcpiGbl_DmResourceDispatch [] =
     59 {
     60     /* Small descriptors */
     61 
     62     NULL,                           /* 0x00, Reserved */
     63     NULL,                           /* 0x01, Reserved */
     64     NULL,                           /* 0x02, Reserved */
     65     NULL,                           /* 0x03, Reserved */
     66     AcpiDmIrqDescriptor,            /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
     67     AcpiDmDmaDescriptor,            /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
     68     AcpiDmStartDependentDescriptor, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
     69     AcpiDmEndDependentDescriptor,   /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
     70     AcpiDmIoDescriptor,             /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
     71     AcpiDmFixedIoDescriptor,        /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
     72     AcpiDmFixedDmaDescriptor,       /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
     73     NULL,                           /* 0x0B, Reserved */
     74     NULL,                           /* 0x0C, Reserved */
     75     NULL,                           /* 0x0D, Reserved */
     76     AcpiDmVendorSmallDescriptor,    /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
     77     NULL,                           /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
     78 
     79     /* Large descriptors */
     80 
     81     NULL,                           /* 0x00, Reserved */
     82     AcpiDmMemory24Descriptor,       /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
     83     AcpiDmGenericRegisterDescriptor,/* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
     84     NULL,                           /* 0x03, Reserved */
     85     AcpiDmVendorLargeDescriptor,    /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
     86     AcpiDmMemory32Descriptor,       /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
     87     AcpiDmFixedMemory32Descriptor,  /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
     88     AcpiDmDwordDescriptor,          /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
     89     AcpiDmWordDescriptor,           /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
     90     AcpiDmInterruptDescriptor,      /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
     91     AcpiDmQwordDescriptor,          /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
     92     AcpiDmExtendedDescriptor,       /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
     93     AcpiDmGpioDescriptor,           /* 0x0C, ACPI_RESOURCE_NAME_GPIO */
     94     NULL,                           /* 0x0D, Reserved */
     95     AcpiDmSerialBusDescriptor       /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS */
     96 };
     97 
     98 
     99 /* Only used for single-threaded applications */
    100 /* TBD: remove when name is passed as parameter to the dump functions */
    101 
    102 static UINT32               ResourceName;
    103 
    104 
    105 /*******************************************************************************
    106  *
    107  * FUNCTION:    AcpiDmDescriptorName
    108  *
    109  * PARAMETERS:  None
    110  *
    111  * RETURN:      None
    112  *
    113  * DESCRIPTION: Emit a name for the descriptor if one is present (indicated
    114  *              by the name being changed from the default name.) A name is only
    115  *              emitted if a reference to the descriptor has been made somewhere
    116  *              in the original ASL code.
    117  *
    118  ******************************************************************************/
    119 
    120 void
    121 AcpiDmDescriptorName (
    122     void)
    123 {
    124 
    125     if (ResourceName == ACPI_DEFAULT_RESNAME)
    126     {
    127         return;
    128     }
    129 
    130     AcpiOsPrintf ("%4.4s", (char *) &ResourceName);
    131 }
    132 
    133 
    134 /*******************************************************************************
    135  *
    136  * FUNCTION:    AcpiDmDumpInteger*
    137  *
    138  * PARAMETERS:  Value               - Value to emit
    139  *              Name                - Associated name (emitted as a comment)
    140  *
    141  * RETURN:      None
    142  *
    143  * DESCRIPTION: Integer output helper functions
    144  *
    145  ******************************************************************************/
    146 
    147 void
    148 AcpiDmDumpInteger8 (
    149     UINT8                   Value,
    150     const char              *Name)
    151 {
    152     AcpiOsPrintf ("0x%2.2X,               // %s\n", Value, Name);
    153 }
    154 
    155 void
    156 AcpiDmDumpInteger16 (
    157     UINT16                  Value,
    158     const char              *Name)
    159 {
    160     AcpiOsPrintf ("0x%4.4X,             // %s\n", Value, Name);
    161 }
    162 
    163 void
    164 AcpiDmDumpInteger32 (
    165     UINT32                  Value,
    166     const char              *Name)
    167 {
    168     AcpiOsPrintf ("0x%8.8X,         // %s\n", Value, Name);
    169 }
    170 
    171 void
    172 AcpiDmDumpInteger64 (
    173     UINT64                  Value,
    174     const char              *Name)
    175 {
    176     AcpiOsPrintf ("0x%8.8X%8.8X, // %s\n", ACPI_FORMAT_UINT64 (Value), Name);
    177 }
    178 
    179 
    180 /*******************************************************************************
    181  *
    182  * FUNCTION:    AcpiDmBitList
    183  *
    184  * PARAMETERS:  Mask            - 16-bit value corresponding to 16 interrupt
    185  *                                or DMA values
    186  *
    187  * RETURN:      None
    188  *
    189  * DESCRIPTION: Dump a bit mask as a list of individual interrupt/DMA levels.
    190  *
    191  ******************************************************************************/
    192 
    193 void
    194 AcpiDmBitList (
    195     UINT16                  Mask)
    196 {
    197     UINT32                  i;
    198     BOOLEAN                 Previous = FALSE;
    199 
    200 
    201     /* Open the initializer list */
    202 
    203     AcpiOsPrintf ("{");
    204 
    205     /* Examine each bit */
    206 
    207     for (i = 0; i < 16; i++)
    208     {
    209         /* Only interested in bits that are set to 1 */
    210 
    211         if (Mask & 1)
    212         {
    213             if (Previous)
    214             {
    215                 AcpiOsPrintf (",");
    216             }
    217             Previous = TRUE;
    218             AcpiOsPrintf ("%u", i);
    219         }
    220 
    221         Mask >>= 1;
    222     }
    223 
    224     /* Close list */
    225 
    226     AcpiOsPrintf ("}\n");
    227 }
    228 
    229 
    230 /*******************************************************************************
    231  *
    232  * FUNCTION:    AcpiDmResourceTemplate
    233  *
    234  * PARAMETERS:  Info            - Curent parse tree walk info
    235  *              ByteData        - Pointer to the byte list data
    236  *              ByteCount       - Length of the byte list
    237  *
    238  * RETURN:      None
    239  *
    240  * DESCRIPTION: Dump the contents of a Resource Template containing a set of
    241  *              Resource Descriptors.
    242  *
    243  ******************************************************************************/
    244 
    245 void
    246 AcpiDmResourceTemplate (
    247     ACPI_OP_WALK_INFO       *Info,
    248     ACPI_PARSE_OBJECT       *Op,
    249     UINT8                   *ByteData,
    250     UINT32                  ByteCount)
    251 {
    252     ACPI_STATUS             Status;
    253     UINT32                  CurrentByteOffset;
    254     UINT8                   ResourceType;
    255     UINT32                  ResourceLength;
    256     void                    *Aml;
    257     UINT32                  Level;
    258     BOOLEAN                 DependentFns = FALSE;
    259     UINT8                   ResourceIndex;
    260     ACPI_NAMESPACE_NODE     *Node;
    261 
    262 
    263     Level = Info->Level;
    264     ResourceName = ACPI_DEFAULT_RESNAME;
    265     Node = Op->Common.Node;
    266     if (Node)
    267     {
    268         Node = Node->Child;
    269     }
    270 
    271     for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;)
    272     {
    273         Aml = &ByteData[CurrentByteOffset];
    274 
    275         /* Get the descriptor type and length */
    276 
    277         ResourceType = AcpiUtGetResourceType (Aml);
    278         ResourceLength = AcpiUtGetResourceLength (Aml);
    279 
    280         /* Validate the Resource Type and Resource Length */
    281 
    282         Status = AcpiUtValidateResource (NULL, Aml, &ResourceIndex);
    283         if (ACPI_FAILURE (Status))
    284         {
    285             AcpiOsPrintf ("/*** Could not validate Resource, type (%X) %s***/\n",
    286                 ResourceType, AcpiFormatException (Status));
    287             return;
    288         }
    289 
    290         /* Point to next descriptor */
    291 
    292         CurrentByteOffset += AcpiUtGetDescriptorLength (Aml);
    293 
    294         /* Descriptor pre-processing */
    295 
    296         switch (ResourceType)
    297         {
    298         case ACPI_RESOURCE_NAME_START_DEPENDENT:
    299 
    300             /* Finish a previous StartDependentFns */
    301 
    302             if (DependentFns)
    303             {
    304                 Level--;
    305                 AcpiDmIndent (Level);
    306                 AcpiOsPrintf ("}\n");
    307             }
    308             break;
    309 
    310         case ACPI_RESOURCE_NAME_END_DEPENDENT:
    311 
    312             Level--;
    313             DependentFns = FALSE;
    314             break;
    315 
    316         case ACPI_RESOURCE_NAME_END_TAG:
    317 
    318             /* Normal exit, the resource list is finished */
    319 
    320             if (DependentFns)
    321             {
    322                 /*
    323                  * Close an open StartDependentDescriptor. This indicates a
    324                  * missing EndDependentDescriptor.
    325                  */
    326                 Level--;
    327                 DependentFns = FALSE;
    328 
    329                 /* Go ahead and insert EndDependentFn() */
    330 
    331                 AcpiDmEndDependentDescriptor (Aml, ResourceLength, Level);
    332 
    333                 AcpiDmIndent (Level);
    334                 AcpiOsPrintf (
    335                     "/*** Disassembler: inserted missing EndDependentFn () ***/\n");
    336             }
    337             return;
    338 
    339         default:
    340 
    341             break;
    342         }
    343 
    344         /* Disassemble the resource structure */
    345 
    346         if (Node)
    347         {
    348             ResourceName = Node->Name.Integer;
    349             Node = Node->Peer;
    350         }
    351 
    352         AcpiGbl_DmResourceDispatch [ResourceIndex] (
    353             Aml, ResourceLength, Level);
    354 
    355         /* Descriptor post-processing */
    356 
    357         if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT)
    358         {
    359             DependentFns = TRUE;
    360             Level++;
    361         }
    362     }
    363 }
    364 
    365 
    366 /*******************************************************************************
    367  *
    368  * FUNCTION:    AcpiDmIsResourceTemplate
    369  *
    370  * PARAMETERS:  WalkState           - Current walk info
    371  *              Op                  - Buffer Op to be examined
    372  *
    373  * RETURN:      Status. AE_OK if valid template
    374  *
    375  * DESCRIPTION: Walk a byte list to determine if it consists of a valid set
    376  *              of resource descriptors. Nothing is output.
    377  *
    378  ******************************************************************************/
    379 
    380 ACPI_STATUS
    381 AcpiDmIsResourceTemplate (
    382     ACPI_WALK_STATE         *WalkState,
    383     ACPI_PARSE_OBJECT       *Op)
    384 {
    385     ACPI_STATUS             Status;
    386     ACPI_PARSE_OBJECT       *NextOp;
    387     UINT8                   *Aml;
    388     UINT8                   *EndAml;
    389     ACPI_SIZE               Length;
    390 
    391 
    392     /* This op must be a buffer */
    393 
    394     if (Op->Common.AmlOpcode != AML_BUFFER_OP)
    395     {
    396         return (AE_TYPE);
    397     }
    398 
    399     /* Get the ByteData list and length */
    400 
    401     NextOp = Op->Common.Value.Arg;
    402     if (!NextOp)
    403     {
    404         AcpiOsPrintf ("NULL byte list in buffer\n");
    405         return (AE_TYPE);
    406     }
    407 
    408     NextOp = NextOp->Common.Next;
    409     if (!NextOp)
    410     {
    411         return (AE_TYPE);
    412     }
    413 
    414     Aml = NextOp->Named.Data;
    415     Length = (ACPI_SIZE) NextOp->Common.Value.Integer;
    416 
    417     /* Walk the byte list, abort on any invalid descriptor type or length */
    418 
    419     Status = AcpiUtWalkAmlResources (WalkState, Aml, Length,
    420         NULL, ACPI_CAST_INDIRECT_PTR (void, &EndAml));
    421     if (ACPI_FAILURE (Status))
    422     {
    423         return (AE_TYPE);
    424     }
    425 
    426     /*
    427      * For the resource template to be valid, one EndTag must appear
    428      * at the very end of the ByteList, not before. (For proper disassembly
    429      * of a ResourceTemplate, the buffer must not have any extra data after
    430      * the EndTag.)
    431      */
    432     if ((Aml + Length - sizeof (AML_RESOURCE_END_TAG)) != EndAml)
    433     {
    434         return (AE_AML_NO_RESOURCE_END_TAG);
    435     }
    436 
    437     /*
    438      * All resource descriptors are valid, therefore this list appears
    439      * to be a valid resource template
    440      */
    441     return (AE_OK);
    442 }
    443 
    444 #endif
    445