1 /*******************************************************************************
   2  *
   3  * Module Name: dmutils - AML disassembler utilities
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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_ASL_COMPILER
  51 #include <acnamesp.h>
  52 #endif
  53 
  54 #ifdef ACPI_DISASSEMBLER
  55 
  56 #define _COMPONENT          ACPI_CA_DEBUGGER
  57         ACPI_MODULE_NAME    ("dmutils")
  58 
  59 
  60 /* Data used in keeping track of fields */
  61 #if 0
  62 const char                      *AcpiGbl_FENames[] =
  63 {
  64     "skip",
  65     "?access?"
  66 };              /* FE = Field Element */
  67 #endif
  68 
  69 /* Operators for Match() */
  70 
  71 const char                      *AcpiGbl_MatchOps[] =
  72 {
  73     "MTR",
  74     "MEQ",
  75     "MLE",
  76     "MLT",
  77     "MGE",
  78     "MGT"
  79 };
  80 
  81 /* Access type decoding */
  82 
  83 const char                      *AcpiGbl_AccessTypes[] =
  84 {
  85     "AnyAcc",
  86     "ByteAcc",
  87     "WordAcc",
  88     "DWordAcc",
  89     "QWordAcc",
  90     "BufferAcc",
  91     "InvalidAccType",
  92     "InvalidAccType"
  93 };
  94 
  95 /* Lock rule decoding */
  96 
  97 const char                      *AcpiGbl_LockRule[] =
  98 {
  99     "NoLock",
 100     "Lock"
 101 };
 102 
 103 /* Update rule decoding */
 104 
 105 const char                      *AcpiGbl_UpdateRules[] =
 106 {
 107     "Preserve",
 108     "WriteAsOnes",
 109     "WriteAsZeros",
 110     "InvalidUpdateRule"
 111 };
 112 
 113 /* Strings used to decode resource descriptors */
 114 
 115 const char                      *AcpiGbl_WordDecode[] =
 116 {
 117     "Memory",
 118     "IO",
 119     "BusNumber",
 120     "UnknownResourceType"
 121 };
 122 
 123 const char                      *AcpiGbl_IrqDecode[] =
 124 {
 125     "IRQNoFlags",
 126     "IRQ"
 127 };
 128 
 129 
 130 /*******************************************************************************
 131  *
 132  * FUNCTION:    AcpiDmDecodeAttribute
 133  *
 134  * PARAMETERS:  Attribute       - Attribute field of AccessAs keyword
 135  *
 136  * RETURN:      None
 137  *
 138  * DESCRIPTION: Decode the AccessAs attribute byte. (Mostly SMBus and
 139  *              GenericSerialBus stuff.)
 140  *
 141  ******************************************************************************/
 142 
 143 void
 144 AcpiDmDecodeAttribute (
 145     UINT8                   Attribute)
 146 {
 147 
 148     switch (Attribute)
 149     {
 150     case AML_FIELD_ATTRIB_QUICK:
 151 
 152         AcpiOsPrintf ("AttribQuick");
 153         break;
 154 
 155     case AML_FIELD_ATTRIB_SEND_RCV:
 156 
 157         AcpiOsPrintf ("AttribSendReceive");
 158         break;
 159 
 160     case AML_FIELD_ATTRIB_BYTE:
 161 
 162         AcpiOsPrintf ("AttribByte");
 163         break;
 164 
 165     case AML_FIELD_ATTRIB_WORD:
 166 
 167         AcpiOsPrintf ("AttribWord");
 168         break;
 169 
 170     case AML_FIELD_ATTRIB_BLOCK:
 171 
 172         AcpiOsPrintf ("AttribBlock");
 173         break;
 174 
 175     case AML_FIELD_ATTRIB_MULTIBYTE:
 176 
 177         AcpiOsPrintf ("AttribBytes");
 178         break;
 179 
 180     case AML_FIELD_ATTRIB_WORD_CALL:
 181 
 182         AcpiOsPrintf ("AttribProcessCall");
 183         break;
 184 
 185     case AML_FIELD_ATTRIB_BLOCK_CALL:
 186 
 187         AcpiOsPrintf ("AttribBlockProcessCall");
 188         break;
 189 
 190     case AML_FIELD_ATTRIB_RAW_BYTES:
 191 
 192         AcpiOsPrintf ("AttribRawBytes");
 193         break;
 194 
 195     case AML_FIELD_ATTRIB_RAW_PROCESS:
 196 
 197         AcpiOsPrintf ("AttribRawProcessBytes");
 198         break;
 199 
 200     default:
 201 
 202         /* A ByteConst is allowed by the grammar */
 203 
 204         AcpiOsPrintf ("0x%2.2X", Attribute);
 205         break;
 206     }
 207 }
 208 
 209 
 210 /*******************************************************************************
 211  *
 212  * FUNCTION:    AcpiDmIndent
 213  *
 214  * PARAMETERS:  Level               - Current source code indentation level
 215  *
 216  * RETURN:      None
 217  *
 218  * DESCRIPTION: Indent 4 spaces per indentation level.
 219  *
 220  ******************************************************************************/
 221 
 222 void
 223 AcpiDmIndent (
 224     UINT32                  Level)
 225 {
 226 
 227     if (!Level)
 228     {
 229         return;
 230     }
 231 
 232     AcpiOsPrintf ("%*.s", ACPI_MUL_4 (Level), " ");
 233 }
 234 
 235 
 236 /*******************************************************************************
 237  *
 238  * FUNCTION:    AcpiDmCommaIfListMember
 239  *
 240  * PARAMETERS:  Op              - Current operator/operand
 241  *
 242  * RETURN:      TRUE if a comma was inserted
 243  *
 244  * DESCRIPTION: Insert a comma if this Op is a member of an argument list.
 245  *
 246  ******************************************************************************/
 247 
 248 BOOLEAN
 249 AcpiDmCommaIfListMember (
 250     ACPI_PARSE_OBJECT       *Op)
 251 {
 252 
 253     if (!Op->Common.Next)
 254     {
 255         return (FALSE);
 256     }
 257 
 258     if (AcpiDmListType (Op->Common.Parent) & BLOCK_COMMA_LIST)
 259     {
 260         /* Check for a NULL target operand */
 261 
 262         if ((Op->Common.Next->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
 263             (!Op->Common.Next->Common.Value.String))
 264         {
 265             /*
 266              * To handle the Divide() case where there are two optional
 267              * targets, look ahead one more op. If null, this null target
 268              * is the one and only target -- no comma needed. Otherwise,
 269              * we need a comma to prepare for the next target.
 270              */
 271             if (!Op->Common.Next->Common.Next)
 272             {
 273                 return (FALSE);
 274             }
 275         }
 276 
 277         if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) &&
 278             (!(Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)))
 279         {
 280             return (FALSE);
 281         }
 282 
 283         AcpiOsPrintf (", ");
 284         return (TRUE);
 285     }
 286 
 287     else if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) &&
 288              (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
 289     {
 290         AcpiOsPrintf (", ");
 291         return (TRUE);
 292     }
 293 
 294     return (FALSE);
 295 }
 296 
 297 
 298 /*******************************************************************************
 299  *
 300  * FUNCTION:    AcpiDmCommaIfFieldMember
 301  *
 302  * PARAMETERS:  Op              - Current operator/operand
 303  *
 304  * RETURN:      None
 305  *
 306  * DESCRIPTION: Insert a comma if this Op is a member of a Field argument list.
 307  *
 308  ******************************************************************************/
 309 
 310 void
 311 AcpiDmCommaIfFieldMember (
 312     ACPI_PARSE_OBJECT       *Op)
 313 {
 314 
 315     if (Op->Common.Next)
 316     {
 317         AcpiOsPrintf (", ");
 318     }
 319 }
 320 
 321 #endif