dmopcode.c revision 228110
1238104Sdes/******************************************************************************* 2238104Sdes * 3238104Sdes * Module Name: dmopcode - AML disassembler, specific AML opcodes 4238104Sdes * 5238104Sdes ******************************************************************************/ 6238104Sdes 7238104Sdes/* 8238104Sdes * Copyright (C) 2000 - 2011, Intel Corp. 9238104Sdes * All rights reserved. 10238104Sdes * 11238104Sdes * Redistribution and use in source and binary forms, with or without 12238104Sdes * modification, are permitted provided that the following conditions 13238104Sdes * are met: 14238104Sdes * 1. Redistributions of source code must retain the above copyright 15238104Sdes * notice, this list of conditions, and the following disclaimer, 16238104Sdes * without modification. 17238104Sdes * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18238104Sdes * substantially similar to the "NO WARRANTY" disclaimer below 19238104Sdes * ("Disclaimer") and any redistribution must be conditioned upon 20238104Sdes * including a substantially similar Disclaimer requirement for further 21238104Sdes * binary redistribution. 22238104Sdes * 3. Neither the names of the above-listed copyright holders nor the names 23238104Sdes * of any contributors may be used to endorse or promote products derived 24238104Sdes * from this software without specific prior written permission. 25238104Sdes * 26238104Sdes * Alternatively, this software may be distributed under the terms of the 27238104Sdes * GNU General Public License ("GPL") version 2 as published by the Free 28238104Sdes * Software Foundation. 29238104Sdes * 30238104Sdes * NO WARRANTY 31238104Sdes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32238104Sdes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33238104Sdes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34238104Sdes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35238104Sdes * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36238104Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37238104Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38238104Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39238104Sdes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40238104Sdes * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41238104Sdes * POSSIBILITY OF SUCH DAMAGES. 42238104Sdes */ 43238104Sdes 44238104Sdes#include <contrib/dev/acpica/include/acpi.h> 45238104Sdes#include <contrib/dev/acpica/include/accommon.h> 46238104Sdes#include <contrib/dev/acpica/include/acparser.h> 47238104Sdes#include <contrib/dev/acpica/include/amlcode.h> 48238104Sdes#include <contrib/dev/acpica/include/acdisasm.h> 49238104Sdes 50238104Sdes#ifdef ACPI_DISASSEMBLER 51238104Sdes 52238104Sdes#define _COMPONENT ACPI_CA_DEBUGGER 53238104Sdes ACPI_MODULE_NAME ("dmopcode") 54238104Sdes 55238104Sdes/* Local prototypes */ 56238104Sdes 57238104Sdesstatic void 58238104SdesAcpiDmMatchKeyword ( 59238104Sdes ACPI_PARSE_OBJECT *Op); 60238104Sdes 61238104Sdes 62238104Sdes/******************************************************************************* 63238104Sdes * 64238104Sdes * FUNCTION: AcpiDmMethodFlags 65238104Sdes * 66238104Sdes * PARAMETERS: Op - Method Object to be examined 67238104Sdes * 68238104Sdes * RETURN: None 69238104Sdes * 70238104Sdes * DESCRIPTION: Decode control method flags 71238104Sdes * 72238104Sdes ******************************************************************************/ 73238104Sdes 74238104Sdesvoid 75238104SdesAcpiDmMethodFlags ( 76238104Sdes ACPI_PARSE_OBJECT *Op) 77238104Sdes{ 78238104Sdes UINT32 Flags; 79238104Sdes UINT32 Args; 80238104Sdes 81238104Sdes 82238104Sdes /* The next Op contains the flags */ 83238104Sdes 84238104Sdes Op = AcpiPsGetDepthNext (NULL, Op); 85238104Sdes Flags = (UINT8) Op->Common.Value.Integer; 86238104Sdes Args = Flags & 0x07; 87238104Sdes 88238104Sdes /* Mark the Op as completed */ 89238104Sdes 90238104Sdes Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 91238104Sdes 92238104Sdes /* 1) Method argument count */ 93238104Sdes 94238104Sdes AcpiOsPrintf (", %u, ", Args); 95238104Sdes 96238104Sdes /* 2) Serialize rule */ 97238104Sdes 98238104Sdes if (!(Flags & 0x08)) 99238104Sdes { 100238104Sdes AcpiOsPrintf ("Not"); 101238104Sdes } 102238104Sdes 103238104Sdes AcpiOsPrintf ("Serialized"); 104238104Sdes 105238104Sdes /* 3) SyncLevel */ 106238104Sdes 107238104Sdes if (Flags & 0xF0) 108238104Sdes { 109238104Sdes AcpiOsPrintf (", %u", Flags >> 4); 110238104Sdes } 111238104Sdes} 112238104Sdes 113238104Sdes 114238104Sdes/******************************************************************************* 115238104Sdes * 116238104Sdes * FUNCTION: AcpiDmFieldFlags 117238104Sdes * 118238104Sdes * PARAMETERS: Op - Field Object to be examined 119238104Sdes * 120238104Sdes * RETURN: None 121238104Sdes * 122238104Sdes * DESCRIPTION: Decode Field definition flags 123238104Sdes * 124238104Sdes ******************************************************************************/ 125238104Sdes 126238104Sdesvoid 127238104SdesAcpiDmFieldFlags ( 128238104Sdes ACPI_PARSE_OBJECT *Op) 129238104Sdes{ 130238104Sdes UINT32 Flags; 131238104Sdes 132238104Sdes 133238104Sdes Op = Op->Common.Next; 134238104Sdes Flags = (UINT8) Op->Common.Value.Integer; 135238104Sdes 136238104Sdes /* Mark the Op as completed */ 137238104Sdes 138238104Sdes Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 139238104Sdes 140238104Sdes AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]); 141238104Sdes AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]); 142238104Sdes AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]); 143238104Sdes} 144238104Sdes 145238104Sdes 146238104Sdes/******************************************************************************* 147238104Sdes * 148238104Sdes * FUNCTION: AcpiDmAddressSpace 149238104Sdes * 150238104Sdes * PARAMETERS: SpaceId - ID to be translated 151238104Sdes * 152238104Sdes * RETURN: None 153238104Sdes * 154238104Sdes * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword 155238104Sdes * 156238104Sdes ******************************************************************************/ 157238104Sdes 158238104Sdesvoid 159238104SdesAcpiDmAddressSpace ( 160238104Sdes UINT8 SpaceId) 161238104Sdes{ 162238104Sdes 163238104Sdes if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS) 164238104Sdes { 165238104Sdes if (SpaceId == 0x7F) 166238104Sdes { 167238104Sdes AcpiOsPrintf ("FFixedHW, "); 168238104Sdes } 169238104Sdes else 170238104Sdes { 171238104Sdes AcpiOsPrintf ("0x%.2X, ", SpaceId); 172238104Sdes } 173238104Sdes } 174238104Sdes else 175238104Sdes { 176238104Sdes AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]); 177238104Sdes } 178238104Sdes} 179238104Sdes 180238104Sdes 181238104Sdes/******************************************************************************* 182238104Sdes * 183238104Sdes * FUNCTION: AcpiDmRegionFlags 184238104Sdes * 185238104Sdes * PARAMETERS: Op - Object to be examined 186238104Sdes * 187238104Sdes * RETURN: None 188238104Sdes * 189238104Sdes * DESCRIPTION: Decode OperationRegion flags 190238104Sdes * 191238104Sdes ******************************************************************************/ 192238104Sdes 193238104Sdesvoid 194238104SdesAcpiDmRegionFlags ( 195238104Sdes ACPI_PARSE_OBJECT *Op) 196238104Sdes{ 197238104Sdes 198238104Sdes 199238104Sdes /* The next Op contains the SpaceId */ 200238104Sdes 201238104Sdes Op = AcpiPsGetDepthNext (NULL, Op); 202238104Sdes 203238104Sdes /* Mark the Op as completed */ 204238104Sdes 205238104Sdes Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 206238104Sdes 207238104Sdes AcpiOsPrintf (", "); 208238104Sdes AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer); 209238104Sdes} 210238104Sdes 211238104Sdes 212238104Sdes/******************************************************************************* 213238104Sdes * 214238104Sdes * FUNCTION: AcpiDmMatchOp 215238104Sdes * 216238104Sdes * PARAMETERS: Op - Match Object to be examined 217238104Sdes * 218238104Sdes * RETURN: None 219238104Sdes * 220238104Sdes * DESCRIPTION: Decode Match opcode operands 221238104Sdes * 222238104Sdes ******************************************************************************/ 223238104Sdes 224238104Sdesvoid 225238104SdesAcpiDmMatchOp ( 226238104Sdes ACPI_PARSE_OBJECT *Op) 227238104Sdes{ 228238104Sdes ACPI_PARSE_OBJECT *NextOp; 229238104Sdes 230238104Sdes 231238104Sdes NextOp = AcpiPsGetDepthNext (NULL, Op); 232238104Sdes NextOp = NextOp->Common.Next; 233238104Sdes 234238104Sdes if (!NextOp) 235238104Sdes { 236238104Sdes /* Handle partial tree during single-step */ 237238104Sdes 238238104Sdes return; 239238104Sdes } 240238104Sdes 241238104Sdes /* Mark the two nodes that contain the encoding for the match keywords */ 242238104Sdes 243238104Sdes NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP; 244238104Sdes 245238104Sdes NextOp = NextOp->Common.Next; 246238104Sdes NextOp = NextOp->Common.Next; 247238104Sdes NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP; 248238104Sdes} 249238104Sdes 250238104Sdes 251238104Sdes/******************************************************************************* 252238104Sdes * 253238104Sdes * FUNCTION: AcpiDmMatchKeyword 254238104Sdes * 255238104Sdes * PARAMETERS: Op - Match Object to be examined 256238104Sdes * 257238104Sdes * RETURN: None 258238104Sdes * 259238104Sdes * DESCRIPTION: Decode Match opcode operands 260238104Sdes * 261238104Sdes ******************************************************************************/ 262238104Sdes 263238104Sdesstatic void 264238104SdesAcpiDmMatchKeyword ( 265238104Sdes ACPI_PARSE_OBJECT *Op) 266238104Sdes{ 267238104Sdes 268238104Sdes 269238104Sdes if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE) 270238104Sdes { 271238104Sdes AcpiOsPrintf ("/* Unknown Match Keyword encoding */"); 272238104Sdes } 273238104Sdes else 274238104Sdes { 275238104Sdes AcpiOsPrintf ("%s", ACPI_CAST_PTR (char, 276238104Sdes AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer])); 277238104Sdes } 278238104Sdes} 279238104Sdes 280238104Sdes 281238104Sdes/******************************************************************************* 282238104Sdes * 283238104Sdes * FUNCTION: AcpiDmDisassembleOneOp 284238104Sdes * 285238104Sdes * PARAMETERS: WalkState - Current walk info 286238104Sdes * Info - Parse tree walk info 287238104Sdes * Op - Op that is to be printed 288238104Sdes * 289238104Sdes * RETURN: None 290238104Sdes * 291238104Sdes * DESCRIPTION: Disassemble a single AML opcode 292238104Sdes * 293238104Sdes ******************************************************************************/ 294238104Sdes 295238104Sdesvoid 296238104SdesAcpiDmDisassembleOneOp ( 297238104Sdes ACPI_WALK_STATE *WalkState, 298238104Sdes ACPI_OP_WALK_INFO *Info, 299238104Sdes ACPI_PARSE_OBJECT *Op) 300238104Sdes{ 301238104Sdes const ACPI_OPCODE_INFO *OpInfo = NULL; 302238104Sdes UINT32 Offset; 303238104Sdes UINT32 Length; 304238104Sdes ACPI_PARSE_OBJECT *Child; 305238104Sdes ACPI_STATUS Status; 306238104Sdes UINT8 *Aml; 307238104Sdes 308238104Sdes 309238104Sdes if (!Op) 310238104Sdes { 311238104Sdes AcpiOsPrintf ("<NULL OP PTR>"); 312238104Sdes return; 313238104Sdes } 314238104Sdes 315238104Sdes switch (Op->Common.DisasmOpcode) 316238104Sdes { 317238104Sdes case ACPI_DASM_MATCHOP: 318238104Sdes 319238104Sdes AcpiDmMatchKeyword (Op); 320238104Sdes return; 321238104Sdes 322238104Sdes case ACPI_DASM_LNOT_SUFFIX: 323238104Sdes switch (Op->Common.AmlOpcode) 324238104Sdes { 325238104Sdes case AML_LEQUAL_OP: 326238104Sdes AcpiOsPrintf ("LNotEqual"); 327238104Sdes break; 328238104Sdes 329238104Sdes case AML_LGREATER_OP: 330238104Sdes AcpiOsPrintf ("LLessEqual"); 331238104Sdes break; 332238104Sdes 333238104Sdes case AML_LLESS_OP: 334238104Sdes AcpiOsPrintf ("LGreaterEqual"); 335238104Sdes break; 336238104Sdes 337238104Sdes default: 338238104Sdes break; 339238104Sdes } 340238104Sdes Op->Common.DisasmOpcode = 0; 341238104Sdes Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 342238104Sdes return; 343238104Sdes 344238104Sdes default: 345238104Sdes break; 346238104Sdes } 347238104Sdes 348238104Sdes 349238104Sdes OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 350238104Sdes 351238104Sdes /* The op and arguments */ 352238104Sdes 353238104Sdes switch (Op->Common.AmlOpcode) 354238104Sdes { 355238104Sdes case AML_LNOT_OP: 356238104Sdes 357238104Sdes Child = Op->Common.Value.Arg; 358238104Sdes if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) || 359238104Sdes (Child->Common.AmlOpcode == AML_LGREATER_OP) || 360238104Sdes (Child->Common.AmlOpcode == AML_LLESS_OP)) 361238104Sdes { 362238104Sdes Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX; 363238104Sdes 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