dmopcode.c revision 231844
1/******************************************************************************* 2 * 3 * Module Name: dmopcode - AML disassembler, specific AML opcodes 4 * 5 ******************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, 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 <contrib/dev/acpica/include/acpi.h> 45#include <contrib/dev/acpica/include/accommon.h> 46#include <contrib/dev/acpica/include/acparser.h> 47#include <contrib/dev/acpica/include/amlcode.h> 48#include <contrib/dev/acpica/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 57static void 58AcpiDmMatchKeyword ( 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 74void 75AcpiDmMethodFlags ( 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 126void 127AcpiDmFieldFlags ( 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 158void 159AcpiDmAddressSpace ( 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 193void 194AcpiDmRegionFlags ( 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 224void 225AcpiDmMatchOp ( 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 263static void 264AcpiDmMatchKeyword ( 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 295void 296AcpiDmDisassembleOneOp ( 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 UINT8 *Aml; 307 308 309 if (!Op) 310 { 311 AcpiOsPrintf ("<NULL OP PTR>"); 312 return; 313 } 314 315 switch (Op->Common.DisasmOpcode) 316 { 317 case ACPI_DASM_MATCHOP: 318 319 AcpiDmMatchKeyword (Op); 320 return; 321 322 case ACPI_DASM_LNOT_SUFFIX: 323 switch (Op->Common.AmlOpcode) 324 { 325 case AML_LEQUAL_OP: 326 AcpiOsPrintf ("LNotEqual"); 327 break; 328 329 case AML_LGREATER_OP: 330 AcpiOsPrintf ("LLessEqual"); 331 break; 332 333 case AML_LLESS_OP: 334 AcpiOsPrintf ("LGreaterEqual"); 335 break; 336 337 default: 338 break; 339 } 340 Op->Common.DisasmOpcode = 0; 341 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 342 return; 343 344 default: 345 break; 346 } 347 348 349 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 350 351 /* The op and arguments */ 352 353 switch (Op->Common.AmlOpcode) 354 { 355 case AML_LNOT_OP: 356 357 Child = Op->Common.Value.Arg; 358 if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) || 359 (Child->Common.AmlOpcode == AML_LGREATER_OP) || 360 (Child->Common.AmlOpcode == AML_LLESS_OP)) 361 { 362 Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX; 363 Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX; 364 } 365 else 366 { 367 AcpiOsPrintf ("%s", OpInfo->Name); 368 } 369 break; 370 371 case AML_BYTE_OP: 372 373 AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer); 374 break; 375 376 377 case AML_WORD_OP: 378 379 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) 380 { 381 AcpiDmEisaId ((UINT32) Op->Common.Value.Integer); 382 } 383 else 384 { 385 AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer); 386 } 387 break; 388 389 390 case AML_DWORD_OP: 391 392 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) 393 { 394 AcpiDmEisaId ((UINT32) Op->Common.Value.Integer); 395 } 396 else 397 { 398 AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer); 399 } 400 break; 401 402 403 case AML_QWORD_OP: 404 405 AcpiOsPrintf ("0x%8.8X%8.8X", 406 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); 407 break; 408 409 410 case AML_STRING_OP: 411 412 AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX); 413 break; 414 415 416 case AML_BUFFER_OP: 417 418 /* 419 * Determine the type of buffer. We can have one of the following: 420 * 421 * 1) ResourceTemplate containing Resource Descriptors. 422 * 2) Unicode String buffer 423 * 3) ASCII String buffer 424 * 4) Raw data buffer (if none of the above) 425 * 426 * Since there are no special AML opcodes to differentiate these 427 * types of buffers, we have to closely look at the data in the 428 * buffer to determine the type. 429 */ 430 if (!AcpiGbl_NoResourceDisassembly) 431 { 432 Status = AcpiDmIsResourceTemplate (Op); 433 if (ACPI_SUCCESS (Status)) 434 { 435 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE; 436 AcpiOsPrintf ("ResourceTemplate"); 437 break; 438 } 439 else if (Status == AE_AML_NO_RESOURCE_END_TAG) 440 { 441 AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ "); 442 } 443 } 444 445 if (AcpiDmIsUnicodeBuffer (Op)) 446 { 447 Op->Common.DisasmOpcode = ACPI_DASM_UNICODE; 448 AcpiOsPrintf ("Unicode ("); 449 } 450 else if (AcpiDmIsStringBuffer (Op)) 451 { 452 Op->Common.DisasmOpcode = ACPI_DASM_STRING; 453 AcpiOsPrintf ("Buffer"); 454 } 455 else 456 { 457 Op->Common.DisasmOpcode = ACPI_DASM_BUFFER; 458 AcpiOsPrintf ("Buffer"); 459 } 460 break; 461 462 463 case AML_INT_STATICSTRING_OP: 464 465 if (Op->Common.Value.String) 466 { 467 AcpiOsPrintf ("%s", Op->Common.Value.String); 468 } 469 else 470 { 471 AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\""); 472 } 473 break; 474 475 476 case AML_INT_NAMEPATH_OP: 477 478 AcpiDmNamestring (Op->Common.Value.Name); 479 break; 480 481 482 case AML_INT_NAMEDFIELD_OP: 483 484 Length = AcpiDmDumpName (Op->Named.Name); 485 AcpiOsPrintf (",%*.s %u", (unsigned) (5 - Length), " ", 486 (UINT32) Op->Common.Value.Integer); 487 AcpiDmCommaIfFieldMember (Op); 488 489 Info->BitOffset += (UINT32) Op->Common.Value.Integer; 490 break; 491 492 493 case AML_INT_RESERVEDFIELD_OP: 494 495 /* Offset() -- Must account for previous offsets */ 496 497 Offset = (UINT32) Op->Common.Value.Integer; 498 Info->BitOffset += Offset; 499 500 if (Info->BitOffset % 8 == 0) 501 { 502 AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset)); 503 } 504 else 505 { 506 AcpiOsPrintf (" , %u", Offset); 507 } 508 509 AcpiDmCommaIfFieldMember (Op); 510 break; 511 512 513 case AML_INT_ACCESSFIELD_OP: 514 case AML_INT_EXTACCESSFIELD_OP: 515 516 AcpiOsPrintf ("AccessAs (%s, ", 517 AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]); 518 519 AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8)); 520 521 if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP) 522 { 523 AcpiOsPrintf (" (0x%2.2X)", (unsigned) ((Op->Common.Value.Integer >> 16) & 0xFF)); 524 } 525 526 AcpiOsPrintf (")"); 527 AcpiDmCommaIfFieldMember (Op); 528 break; 529 530 531 case AML_INT_CONNECTION_OP: 532 533 /* 534 * Two types of Connection() - one with a buffer object, the 535 * other with a namestring that points to a buffer object. 536 */ 537 AcpiOsPrintf ("Connection ("); 538 Child = Op->Common.Value.Arg; 539 540 if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP) 541 { 542 AcpiOsPrintf ("\n"); 543 544 Aml = Child->Named.Data; 545 Length = (UINT32) Child->Common.Value.Integer; 546 547 Info->Level += 1; 548 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE; 549 AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length); 550 551 Info->Level -= 1; 552 AcpiDmIndent (Info->Level); 553 } 554 else 555 { 556 AcpiDmNamestring (Child->Common.Value.Name); 557 } 558 559 AcpiOsPrintf (")"); 560 AcpiDmCommaIfFieldMember (Op); 561 AcpiOsPrintf ("\n"); 562 563 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */ 564 Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 565 break; 566 567 case AML_INT_BYTELIST_OP: 568 569 AcpiDmByteList (Info, Op); 570 break; 571 572 573 case AML_INT_METHODCALL_OP: 574 575 Op = AcpiPsGetDepthNext (NULL, Op); 576 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 577 578 AcpiDmNamestring (Op->Common.Value.Name); 579 break; 580 581 582 default: 583 584 /* Just get the opcode name and print it */ 585 586 AcpiOsPrintf ("%s", OpInfo->Name); 587 588 589#ifdef ACPI_DEBUGGER 590 591 if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) && 592 (WalkState) && 593 (WalkState->Results) && 594 (WalkState->ResultCount)) 595 { 596 AcpiDmDecodeInternalObject ( 597 WalkState->Results->Results.ObjDesc [ 598 (WalkState->ResultCount - 1) % 599 ACPI_RESULTS_FRAME_OBJ_NUM]); 600 } 601#endif 602 603 break; 604 } 605} 606 607#endif /* ACPI_DISASSEMBLER */ 608