1 /******************************************************************************* 2 * 3 * Module Name: dmopcode - AML disassembler, specific AML opcodes 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2011, 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 #include "acpi.h" 45 #include "accommon.h" 46 #include "acparser.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 ("dmopcode") 54 55 /* Local prototypes */ 56 57 static void 58 AcpiDmMatchKeyword ( 59 ACPI_PARSE_OBJECT *Op); 60 61 62 /******************************************************************************* 63 * 64 * FUNCTION: AcpiDmMethodFlags 65 * 66 * PARAMETERS: Op - Method Object to be examined 67 * 68 * RETURN: None 69 * 70 * DESCRIPTION: Decode control method flags 71 * 72 ******************************************************************************/ 73 74 void 75 AcpiDmMethodFlags ( 76 ACPI_PARSE_OBJECT *Op) 77 { 78 UINT32 Flags; 79 UINT32 Args; 80 81 82 /* The next Op contains the flags */ 83 84 Op = AcpiPsGetDepthNext (NULL, Op); 85 Flags = (UINT8) Op->Common.Value.Integer; 86 Args = Flags & 0x07; 87 88 /* Mark the Op as completed */ 89 90 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 91 92 /* 1) Method argument count */ 93 94 AcpiOsPrintf (", %u, ", Args); 95 96 /* 2) Serialize rule */ 97 98 if (!(Flags & 0x08)) 99 { 100 AcpiOsPrintf ("Not"); 101 } 102 103 AcpiOsPrintf ("Serialized"); 104 105 /* 3) SyncLevel */ 106 107 if (Flags & 0xF0) 108 { 109 AcpiOsPrintf (", %u", Flags >> 4); 110 } 111 } 112 113 114 /******************************************************************************* 115 * 116 * FUNCTION: AcpiDmFieldFlags 117 * 118 * PARAMETERS: Op - Field Object to be examined 119 * 120 * RETURN: None 121 * 122 * DESCRIPTION: Decode Field definition flags 123 * 124 ******************************************************************************/ 125 126 void 127 AcpiDmFieldFlags ( 128 ACPI_PARSE_OBJECT *Op) 129 { 130 UINT32 Flags; 131 132 133 Op = Op->Common.Next; 134 Flags = (UINT8) Op->Common.Value.Integer; 135 136 /* Mark the Op as completed */ 137 138 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 139 140 AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]); 141 AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]); 142 AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]); 143 } 144 145 146 /******************************************************************************* 147 * 148 * FUNCTION: AcpiDmAddressSpace 149 * 150 * PARAMETERS: SpaceId - ID to be translated 151 * 152 * RETURN: None 153 * 154 * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword 155 * 156 ******************************************************************************/ 157 158 void 159 AcpiDmAddressSpace ( 160 UINT8 SpaceId) 161 { 162 163 if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS) 164 { 165 if (SpaceId == 0x7F) 166 { 167 AcpiOsPrintf ("FFixedHW, "); 168 } 169 else 170 { 171 AcpiOsPrintf ("0x%.2X, ", SpaceId); 172 } 173 } 174 else 175 { 176 AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]); 177 } 178 } 179 180 181 /******************************************************************************* 182 * 183 * FUNCTION: AcpiDmRegionFlags 184 * 185 * PARAMETERS: Op - Object to be examined 186 * 187 * RETURN: None 188 * 189 * DESCRIPTION: Decode OperationRegion flags 190 * 191 ******************************************************************************/ 192 193 void 194 AcpiDmRegionFlags ( 195 ACPI_PARSE_OBJECT *Op) 196 { 197 198 199 /* The next Op contains the SpaceId */ 200 201 Op = AcpiPsGetDepthNext (NULL, Op); 202 203 /* Mark the Op as completed */ 204 205 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 206 207 AcpiOsPrintf (", "); 208 AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer); 209 } 210 211 212 /******************************************************************************* 213 * 214 * FUNCTION: AcpiDmMatchOp 215 * 216 * PARAMETERS: Op - Match Object to be examined 217 * 218 * RETURN: None 219 * 220 * DESCRIPTION: Decode Match opcode operands 221 * 222 ******************************************************************************/ 223 224 void 225 AcpiDmMatchOp ( 226 ACPI_PARSE_OBJECT *Op) 227 { 228 ACPI_PARSE_OBJECT *NextOp; 229 230 231 NextOp = AcpiPsGetDepthNext (NULL, Op); 232 NextOp = NextOp->Common.Next; 233 234 if (!NextOp) 235 { 236 /* Handle partial tree during single-step */ 237 238 return; 239 } 240 241 /* Mark the two nodes that contain the encoding for the match keywords */ 242 243 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP; 244 245 NextOp = NextOp->Common.Next; 246 NextOp = NextOp->Common.Next; 247 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP; 248 } 249 250 251 /******************************************************************************* 252 * 253 * FUNCTION: AcpiDmMatchKeyword 254 * 255 * PARAMETERS: Op - Match Object to be examined 256 * 257 * RETURN: None 258 * 259 * DESCRIPTION: Decode Match opcode operands 260 * 261 ******************************************************************************/ 262 263 static void 264 AcpiDmMatchKeyword ( 265 ACPI_PARSE_OBJECT *Op) 266 { 267 268 269 if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE) 270 { 271 AcpiOsPrintf ("/* Unknown Match Keyword encoding */"); 272 } 273 else 274 { 275 AcpiOsPrintf ("%s", ACPI_CAST_PTR (char, 276 AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer])); 277 } 278 } 279 280 281 /******************************************************************************* 282 * 283 * FUNCTION: AcpiDmDisassembleOneOp 284 * 285 * PARAMETERS: WalkState - Current walk info 286 * Info - Parse tree walk info 287 * Op - Op that is to be printed 288 * 289 * RETURN: None 290 * 291 * DESCRIPTION: Disassemble a single AML opcode 292 * 293 ******************************************************************************/ 294 295 void 296 AcpiDmDisassembleOneOp ( 297 ACPI_WALK_STATE *WalkState, 298 ACPI_OP_WALK_INFO *Info, 299 ACPI_PARSE_OBJECT *Op) 300 { 301 const ACPI_OPCODE_INFO *OpInfo = NULL; 302 UINT32 Offset; 303 UINT32 Length; 304 ACPI_PARSE_OBJECT *Child; 305 ACPI_STATUS Status; 306 307 308 if (!Op) 309 { 310 AcpiOsPrintf ("<NULL OP PTR>"); 311 return; 312 } 313 314 switch (Op->Common.DisasmOpcode) 315 { 316 case ACPI_DASM_MATCHOP: 317 318 AcpiDmMatchKeyword (Op); 319 return; 320 321 case ACPI_DASM_LNOT_SUFFIX: 322 switch (Op->Common.AmlOpcode) 323 { 324 case AML_LEQUAL_OP: 325 AcpiOsPrintf ("LNotEqual"); 326 break; 327 328 case AML_LGREATER_OP: 329 AcpiOsPrintf ("LLessEqual"); 330 break; 331 332 case AML_LLESS_OP: 333 AcpiOsPrintf ("LGreaterEqual"); 334 break; 335 336 default: 337 break; 338 } 339 Op->Common.DisasmOpcode = 0; 340 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 341 return; 342 343 default: 344 break; 345 } 346 347 348 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 349 350 /* The op and arguments */ 351 352 switch (Op->Common.AmlOpcode) 353 { 354 case AML_LNOT_OP: 355 356 Child = Op->Common.Value.Arg; 357 if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) || 358 (Child->Common.AmlOpcode == AML_LGREATER_OP) || 359 (Child->Common.AmlOpcode == AML_LLESS_OP)) 360 { 361 Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX; 362 Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX; 363 } 364 else 365 { 366 AcpiOsPrintf ("%s", OpInfo->Name); 367 } 368 break; 369 370 case AML_BYTE_OP: 371 372 AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer); 373 break; 374 375 376 case AML_WORD_OP: 377 378 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) 379 { 380 AcpiDmEisaId ((UINT32) Op->Common.Value.Integer); 381 } 382 else 383 { 384 AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer); 385 } 386 break; 387 388 389 case AML_DWORD_OP: 390 391 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) 392 { 393 AcpiDmEisaId ((UINT32) Op->Common.Value.Integer); 394 } 395 else 396 { 397 AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer); 398 } 399 break; 400 401 402 case AML_QWORD_OP: 403 404 AcpiOsPrintf ("0x%8.8X%8.8X", 405 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); 406 break; 407 408 409 case AML_STRING_OP: 410 411 AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX); 412 break; 413 414 415 case AML_BUFFER_OP: 416 417 /* 418 * Determine the type of buffer. We can have one of the following: 419 * 420 * 1) ResourceTemplate containing Resource Descriptors. 421 * 2) Unicode String buffer 422 * 3) ASCII String buffer 423 * 4) Raw data buffer (if none of the above) 424 * 425 * Since there are no special AML opcodes to differentiate these 426 * types of buffers, we have to closely look at the data in the 427 * buffer to determine the type. 428 */ 429 Status = AcpiDmIsResourceTemplate (Op); 430 if (ACPI_SUCCESS (Status)) 431 { 432 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE; 433 AcpiOsPrintf ("ResourceTemplate"); 434 break; 435 } 436 else if (Status == AE_AML_NO_RESOURCE_END_TAG) 437 { 438 AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ "); 439 } 440 441 if (AcpiDmIsUnicodeBuffer (Op)) 442 { 443 Op->Common.DisasmOpcode = ACPI_DASM_UNICODE; 444 AcpiOsPrintf ("Unicode ("); 445 } 446 else if (AcpiDmIsStringBuffer (Op)) 447 { 448 Op->Common.DisasmOpcode = ACPI_DASM_STRING; 449 AcpiOsPrintf ("Buffer"); 450 } 451 else 452 { 453 Op->Common.DisasmOpcode = ACPI_DASM_BUFFER; 454 AcpiOsPrintf ("Buffer"); 455 } 456 break; 457 458 459 case AML_INT_STATICSTRING_OP: 460 461 if (Op->Common.Value.String) 462 { 463 AcpiOsPrintf ("%s", Op->Common.Value.String); 464 } 465 else 466 { 467 AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\""); 468 } 469 break; 470 471 472 case AML_INT_NAMEPATH_OP: 473 474 AcpiDmNamestring (Op->Common.Value.Name); 475 break; 476 477 478 case AML_INT_NAMEDFIELD_OP: 479 480 Length = AcpiDmDumpName (Op->Named.Name); 481 AcpiOsPrintf (",%*.s %u", (unsigned) (5 - Length), " ", 482 (UINT32) Op->Common.Value.Integer); 483 AcpiDmCommaIfFieldMember (Op); 484 485 Info->BitOffset += (UINT32) Op->Common.Value.Integer; 486 break; 487 488 489 case AML_INT_RESERVEDFIELD_OP: 490 491 /* Offset() -- Must account for previous offsets */ 492 493 Offset = (UINT32) Op->Common.Value.Integer; 494 Info->BitOffset += Offset; 495 496 if (Info->BitOffset % 8 == 0) 497 { 498 AcpiOsPrintf (" Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset)); 499 } 500 else 501 { 502 AcpiOsPrintf (" , %u", Offset); 503 } 504 505 AcpiDmCommaIfFieldMember (Op); 506 break; 507 508 509 case AML_INT_ACCESSFIELD_OP: 510 511 AcpiOsPrintf (" AccessAs (%s, ", 512 AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer >> 8) & 0x7]); 513 514 AcpiDmDecodeAttribute ((UINT8) Op->Common.Value.Integer); 515 AcpiOsPrintf (")"); 516 AcpiDmCommaIfFieldMember (Op); 517 break; 518 519 520 case AML_INT_BYTELIST_OP: 521 522 AcpiDmByteList (Info, Op); 523 break; 524 525 526 case AML_INT_METHODCALL_OP: 527 528 Op = AcpiPsGetDepthNext (NULL, Op); 529 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 530 531 AcpiDmNamestring (Op->Common.Value.Name); 532 break; 533 534 535 default: 536 537 /* Just get the opcode name and print it */ 538 539 AcpiOsPrintf ("%s", OpInfo->Name); 540 541 542 #ifdef ACPI_DEBUGGER 543 544 if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) && 545 (WalkState) && 546 (WalkState->Results) && 547 (WalkState->ResultCount)) 548 { 549 AcpiDmDecodeInternalObject ( 550 WalkState->Results->Results.ObjDesc [ 551 (WalkState->ResultCount - 1) % 552 ACPI_RESULTS_FRAME_OBJ_NUM]); 553 } 554 #endif 555 556 break; 557 } 558 } 559 560 #endif /* ACPI_DISASSEMBLER */ 561