1100966Siwasaki/******************************************************************************* 2100966Siwasaki * 3100966Siwasaki * Module Name: dmopcode - AML disassembler, specific AML opcodes 4100966Siwasaki * 5100966Siwasaki ******************************************************************************/ 6100966Siwasaki 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9100966Siwasaki * All rights reserved. 10100966Siwasaki * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25100966Siwasaki * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29100966Siwasaki * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43100966Siwasaki 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48281075Sdim#include <contrib/dev/acpica/include/acinterp.h> 49281075Sdim#include <contrib/dev/acpica/include/acnamesp.h> 50306536Sjkim#include <contrib/dev/acpica/include/acdebug.h> 51100966Siwasaki 52100966Siwasaki 53102550Siwasaki#define _COMPONENT ACPI_CA_DEBUGGER 54100966Siwasaki ACPI_MODULE_NAME ("dmopcode") 55100966Siwasaki 56281075Sdim 57151937Sjkim/* Local prototypes */ 58100966Siwasaki 59151937Sjkimstatic void 60151937SjkimAcpiDmMatchKeyword ( 61151937Sjkim ACPI_PARSE_OBJECT *Op); 62151937Sjkim 63306536Sjkimstatic void 64306536SjkimAcpiDmConvertToElseIf ( 65306536Sjkim ACPI_PARSE_OBJECT *Op); 66151937Sjkim 67306536Sjkim 68100966Siwasaki/******************************************************************************* 69100966Siwasaki * 70281075Sdim * FUNCTION: AcpiDmDisplayTargetPathname 71281075Sdim * 72281075Sdim * PARAMETERS: Op - Parse object 73281075Sdim * 74281075Sdim * RETURN: None 75281075Sdim * 76281075Sdim * DESCRIPTION: For AML opcodes that have a target operand, display the full 77281075Sdim * pathname for the target, in a comment field. Handles Return() 78281075Sdim * statements also. 79281075Sdim * 80281075Sdim ******************************************************************************/ 81281075Sdim 82281075Sdimvoid 83281075SdimAcpiDmDisplayTargetPathname ( 84281075Sdim ACPI_PARSE_OBJECT *Op) 85281075Sdim{ 86281075Sdim ACPI_PARSE_OBJECT *NextOp; 87281075Sdim ACPI_PARSE_OBJECT *PrevOp = NULL; 88281075Sdim char *Pathname; 89281075Sdim const ACPI_OPCODE_INFO *OpInfo; 90281075Sdim 91281075Sdim 92281075Sdim if (Op->Common.AmlOpcode == AML_RETURN_OP) 93281075Sdim { 94281075Sdim PrevOp = Op->Asl.Value.Arg; 95281075Sdim } 96281075Sdim else 97281075Sdim { 98281075Sdim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 99281075Sdim if (!(OpInfo->Flags & AML_HAS_TARGET)) 100281075Sdim { 101281075Sdim return; 102281075Sdim } 103281075Sdim 104281075Sdim /* Target is the last Op in the arg list */ 105281075Sdim 106281075Sdim NextOp = Op->Asl.Value.Arg; 107281075Sdim while (NextOp) 108281075Sdim { 109281075Sdim PrevOp = NextOp; 110281075Sdim NextOp = PrevOp->Asl.Next; 111281075Sdim } 112281075Sdim } 113281075Sdim 114281075Sdim if (!PrevOp) 115281075Sdim { 116281075Sdim return; 117281075Sdim } 118281075Sdim 119281075Sdim /* We must have a namepath AML opcode */ 120281075Sdim 121281075Sdim if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) 122281075Sdim { 123281075Sdim return; 124281075Sdim } 125281075Sdim 126281075Sdim /* A null string is the "no target specified" case */ 127281075Sdim 128281075Sdim if (!PrevOp->Asl.Value.String) 129281075Sdim { 130281075Sdim return; 131281075Sdim } 132281075Sdim 133281075Sdim /* No node means "unresolved external reference" */ 134281075Sdim 135281075Sdim if (!PrevOp->Asl.Node) 136281075Sdim { 137281075Sdim AcpiOsPrintf (" /* External reference */"); 138281075Sdim return; 139281075Sdim } 140281075Sdim 141281075Sdim /* Ignore if path is already from the root */ 142281075Sdim 143281075Sdim if (*PrevOp->Asl.Value.String == '\\') 144281075Sdim { 145281075Sdim return; 146281075Sdim } 147281075Sdim 148281075Sdim /* Now: we can get the full pathname */ 149281075Sdim 150281075Sdim Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node); 151281075Sdim if (!Pathname) 152281075Sdim { 153281075Sdim return; 154281075Sdim } 155281075Sdim 156281075Sdim AcpiOsPrintf (" /* %s */", Pathname); 157281075Sdim ACPI_FREE (Pathname); 158281075Sdim} 159281075Sdim 160281075Sdim 161281075Sdim/******************************************************************************* 162281075Sdim * 163281075Sdim * FUNCTION: AcpiDmNotifyDescription 164281075Sdim * 165281075Sdim * PARAMETERS: Op - Name() parse object 166281075Sdim * 167281075Sdim * RETURN: None 168281075Sdim * 169281075Sdim * DESCRIPTION: Emit a description comment for the value associated with a 170281075Sdim * Notify() operator. 171281075Sdim * 172281075Sdim ******************************************************************************/ 173281075Sdim 174281075Sdimvoid 175281075SdimAcpiDmNotifyDescription ( 176281075Sdim ACPI_PARSE_OBJECT *Op) 177281075Sdim{ 178281075Sdim ACPI_PARSE_OBJECT *NextOp; 179281075Sdim ACPI_NAMESPACE_NODE *Node; 180281075Sdim UINT8 NotifyValue; 181281075Sdim UINT8 Type = ACPI_TYPE_ANY; 182281075Sdim 183281075Sdim 184281075Sdim /* The notify value is the second argument */ 185281075Sdim 186281075Sdim NextOp = Op->Asl.Value.Arg; 187281075Sdim NextOp = NextOp->Asl.Next; 188281075Sdim 189281075Sdim switch (NextOp->Common.AmlOpcode) 190281075Sdim { 191281075Sdim case AML_ZERO_OP: 192281075Sdim case AML_ONE_OP: 193281075Sdim 194281075Sdim NotifyValue = (UINT8) NextOp->Common.AmlOpcode; 195281075Sdim break; 196281075Sdim 197281075Sdim case AML_BYTE_OP: 198281075Sdim 199281075Sdim NotifyValue = (UINT8) NextOp->Asl.Value.Integer; 200281075Sdim break; 201281075Sdim 202281075Sdim default: 203281075Sdim return; 204281075Sdim } 205281075Sdim 206281075Sdim /* 207281075Sdim * Attempt to get the namespace node so we can determine the object type. 208281075Sdim * Some notify values are dependent on the object type (Device, Thermal, 209281075Sdim * or Processor). 210281075Sdim */ 211281075Sdim Node = Op->Asl.Node; 212281075Sdim if (Node) 213281075Sdim { 214281075Sdim Type = Node->Type; 215281075Sdim } 216281075Sdim 217281075Sdim AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type)); 218281075Sdim} 219281075Sdim 220281075Sdim 221281075Sdim/******************************************************************************* 222281075Sdim * 223237412Sjkim * FUNCTION: AcpiDmPredefinedDescription 224237412Sjkim * 225237412Sjkim * PARAMETERS: Op - Name() parse object 226237412Sjkim * 227237412Sjkim * RETURN: None 228237412Sjkim * 229237412Sjkim * DESCRIPTION: Emit a description comment for a predefined ACPI name. 230237412Sjkim * Used for iASL compiler only. 231237412Sjkim * 232237412Sjkim ******************************************************************************/ 233237412Sjkim 234237412Sjkimvoid 235237412SjkimAcpiDmPredefinedDescription ( 236237412Sjkim ACPI_PARSE_OBJECT *Op) 237237412Sjkim{ 238237412Sjkim#ifdef ACPI_ASL_COMPILER 239237412Sjkim const AH_PREDEFINED_NAME *Info; 240237412Sjkim char *NameString; 241237412Sjkim int LastCharIsDigit; 242237412Sjkim int LastCharsAreHex; 243237412Sjkim 244237412Sjkim 245237412Sjkim if (!Op) 246237412Sjkim { 247237412Sjkim return; 248237412Sjkim } 249237412Sjkim 250237412Sjkim /* Ensure that the comment field is emitted only once */ 251237412Sjkim 252306536Sjkim if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED) 253237412Sjkim { 254237412Sjkim return; 255237412Sjkim } 256306536Sjkim Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED; 257237412Sjkim 258237412Sjkim /* Predefined name must start with an underscore */ 259237412Sjkim 260237412Sjkim NameString = ACPI_CAST_PTR (char, &Op->Named.Name); 261237412Sjkim if (NameString[0] != '_') 262237412Sjkim { 263237412Sjkim return; 264237412Sjkim } 265237412Sjkim 266237412Sjkim /* 267237412Sjkim * Check for the special ACPI names: 268237412Sjkim * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a 269237412Sjkim * (where d=decimal_digit, x=hex_digit, a=anything) 270237412Sjkim * 271237412Sjkim * Convert these to the generic name for table lookup. 272237412Sjkim * Note: NameString is guaranteed to be upper case here. 273237412Sjkim */ 274237412Sjkim LastCharIsDigit = 275306536Sjkim (isdigit ((int) NameString[3])); /* d */ 276237412Sjkim LastCharsAreHex = 277306536Sjkim (isxdigit ((int) NameString[2]) && /* xx */ 278306536Sjkim isxdigit ((int) NameString[3])); 279237412Sjkim 280237412Sjkim switch (NameString[1]) 281237412Sjkim { 282237412Sjkim case 'A': 283250838Sjkim 284237412Sjkim if ((NameString[2] == 'C') && (LastCharIsDigit)) 285237412Sjkim { 286237412Sjkim NameString = "_ACx"; 287237412Sjkim } 288237412Sjkim else if ((NameString[2] == 'L') && (LastCharIsDigit)) 289237412Sjkim { 290237412Sjkim NameString = "_ALx"; 291237412Sjkim } 292237412Sjkim break; 293237412Sjkim 294237412Sjkim case 'E': 295250838Sjkim 296237412Sjkim if ((NameString[2] == 'J') && (LastCharIsDigit)) 297237412Sjkim { 298237412Sjkim NameString = "_EJx"; 299237412Sjkim } 300237412Sjkim else if (LastCharsAreHex) 301237412Sjkim { 302237412Sjkim NameString = "_Exx"; 303237412Sjkim } 304237412Sjkim break; 305237412Sjkim 306237412Sjkim case 'L': 307250838Sjkim 308237412Sjkim if (LastCharsAreHex) 309237412Sjkim { 310237412Sjkim NameString = "_Lxx"; 311237412Sjkim } 312237412Sjkim break; 313237412Sjkim 314237412Sjkim case 'Q': 315250838Sjkim 316237412Sjkim if (LastCharsAreHex) 317237412Sjkim { 318237412Sjkim NameString = "_Qxx"; 319237412Sjkim } 320237412Sjkim break; 321237412Sjkim 322237412Sjkim case 'T': 323250838Sjkim 324237412Sjkim if (NameString[2] == '_') 325237412Sjkim { 326237412Sjkim NameString = "_T_x"; 327237412Sjkim } 328237412Sjkim break; 329237412Sjkim 330237412Sjkim case 'W': 331250838Sjkim 332237412Sjkim if (LastCharsAreHex) 333237412Sjkim { 334237412Sjkim NameString = "_Wxx"; 335237412Sjkim } 336237412Sjkim break; 337237412Sjkim 338237412Sjkim default: 339250838Sjkim 340237412Sjkim break; 341237412Sjkim } 342237412Sjkim 343237412Sjkim /* Match the name in the info table */ 344237412Sjkim 345281075Sdim Info = AcpiAhMatchPredefinedName (NameString); 346281075Sdim if (Info) 347237412Sjkim { 348281075Sdim AcpiOsPrintf (" // %4.4s: %s", 349281075Sdim NameString, ACPI_CAST_PTR (char, Info->Description)); 350237412Sjkim } 351237412Sjkim 352237412Sjkim#endif 353237412Sjkim return; 354237412Sjkim} 355237412Sjkim 356237412Sjkim 357237412Sjkim/******************************************************************************* 358237412Sjkim * 359237412Sjkim * FUNCTION: AcpiDmFieldPredefinedDescription 360237412Sjkim * 361237412Sjkim * PARAMETERS: Op - Parse object 362237412Sjkim * 363237412Sjkim * RETURN: None 364237412Sjkim * 365237412Sjkim * DESCRIPTION: Emit a description comment for a resource descriptor tag 366237412Sjkim * (which is a predefined ACPI name.) Used for iASL compiler only. 367237412Sjkim * 368237412Sjkim ******************************************************************************/ 369237412Sjkim 370237412Sjkimvoid 371237412SjkimAcpiDmFieldPredefinedDescription ( 372237412Sjkim ACPI_PARSE_OBJECT *Op) 373237412Sjkim{ 374237412Sjkim#ifdef ACPI_ASL_COMPILER 375237412Sjkim ACPI_PARSE_OBJECT *IndexOp; 376237412Sjkim char *Tag; 377237412Sjkim const ACPI_OPCODE_INFO *OpInfo; 378237412Sjkim const AH_PREDEFINED_NAME *Info; 379237412Sjkim 380237412Sjkim 381237412Sjkim if (!Op) 382237412Sjkim { 383237412Sjkim return; 384237412Sjkim } 385237412Sjkim 386237412Sjkim /* Ensure that the comment field is emitted only once */ 387237412Sjkim 388306536Sjkim if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED) 389237412Sjkim { 390237412Sjkim return; 391237412Sjkim } 392306536Sjkim Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED; 393237412Sjkim 394237412Sjkim /* 395237412Sjkim * Op must be one of the Create* operators: CreateField, CreateBitField, 396237412Sjkim * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField 397237412Sjkim */ 398237412Sjkim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 399237412Sjkim if (!(OpInfo->Flags & AML_CREATE)) 400237412Sjkim { 401237412Sjkim return; 402237412Sjkim } 403237412Sjkim 404237412Sjkim /* Second argument is the Index argument */ 405237412Sjkim 406237412Sjkim IndexOp = Op->Common.Value.Arg; 407237412Sjkim IndexOp = IndexOp->Common.Next; 408237412Sjkim 409237412Sjkim /* Index argument must be a namepath */ 410237412Sjkim 411237412Sjkim if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP) 412237412Sjkim { 413237412Sjkim return; 414237412Sjkim } 415237412Sjkim 416237412Sjkim /* Major cheat: We previously put the Tag ptr in the Node field */ 417237412Sjkim 418237412Sjkim Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node); 419240716Sjkim if (!Tag) 420240716Sjkim { 421240716Sjkim return; 422240716Sjkim } 423237412Sjkim 424237412Sjkim /* Match the name in the info table */ 425237412Sjkim 426281075Sdim Info = AcpiAhMatchPredefinedName (Tag); 427281075Sdim if (Info) 428237412Sjkim { 429281075Sdim AcpiOsPrintf (" // %4.4s: %s", Tag, 430281075Sdim ACPI_CAST_PTR (char, Info->Description)); 431237412Sjkim } 432237412Sjkim 433237412Sjkim#endif 434237412Sjkim return; 435237412Sjkim} 436237412Sjkim 437237412Sjkim 438237412Sjkim/******************************************************************************* 439237412Sjkim * 440100966Siwasaki * FUNCTION: AcpiDmMethodFlags 441100966Siwasaki * 442100966Siwasaki * PARAMETERS: Op - Method Object to be examined 443100966Siwasaki * 444100966Siwasaki * RETURN: None 445100966Siwasaki * 446100966Siwasaki * DESCRIPTION: Decode control method flags 447100966Siwasaki * 448100966Siwasaki ******************************************************************************/ 449100966Siwasaki 450100966Siwasakivoid 451100966SiwasakiAcpiDmMethodFlags ( 452100966Siwasaki ACPI_PARSE_OBJECT *Op) 453100966Siwasaki{ 454100966Siwasaki UINT32 Flags; 455100966Siwasaki UINT32 Args; 456100966Siwasaki 457100966Siwasaki 458100966Siwasaki /* The next Op contains the flags */ 459100966Siwasaki 460100966Siwasaki Op = AcpiPsGetDepthNext (NULL, Op); 461117521Snjl Flags = (UINT8) Op->Common.Value.Integer; 462100966Siwasaki Args = Flags & 0x07; 463100966Siwasaki 464100966Siwasaki /* Mark the Op as completed */ 465100966Siwasaki 466100966Siwasaki Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 467100966Siwasaki 468100966Siwasaki /* 1) Method argument count */ 469100966Siwasaki 470209746Sjkim AcpiOsPrintf (", %u, ", Args); 471100966Siwasaki 472100966Siwasaki /* 2) Serialize rule */ 473100966Siwasaki 474100966Siwasaki if (!(Flags & 0x08)) 475100966Siwasaki { 476100966Siwasaki AcpiOsPrintf ("Not"); 477100966Siwasaki } 478100966Siwasaki 479100966Siwasaki AcpiOsPrintf ("Serialized"); 480100966Siwasaki 481100966Siwasaki /* 3) SyncLevel */ 482100966Siwasaki 483100966Siwasaki if (Flags & 0xF0) 484100966Siwasaki { 485209746Sjkim AcpiOsPrintf (", %u", Flags >> 4); 486100966Siwasaki } 487100966Siwasaki} 488100966Siwasaki 489100966Siwasaki 490100966Siwasaki/******************************************************************************* 491100966Siwasaki * 492100966Siwasaki * FUNCTION: AcpiDmFieldFlags 493100966Siwasaki * 494100966Siwasaki * PARAMETERS: Op - Field Object to be examined 495100966Siwasaki * 496100966Siwasaki * RETURN: None 497100966Siwasaki * 498100966Siwasaki * DESCRIPTION: Decode Field definition flags 499100966Siwasaki * 500100966Siwasaki ******************************************************************************/ 501100966Siwasaki 502100966Siwasakivoid 503100966SiwasakiAcpiDmFieldFlags ( 504100966Siwasaki ACPI_PARSE_OBJECT *Op) 505100966Siwasaki{ 506100966Siwasaki UINT32 Flags; 507100966Siwasaki 508100966Siwasaki 509167802Sjkim Op = Op->Common.Next; 510117521Snjl Flags = (UINT8) Op->Common.Value.Integer; 511100966Siwasaki 512100966Siwasaki /* Mark the Op as completed */ 513100966Siwasaki 514100966Siwasaki Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 515100966Siwasaki 516167802Sjkim AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]); 517100966Siwasaki AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]); 518100966Siwasaki AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]); 519100966Siwasaki} 520100966Siwasaki 521100966Siwasaki 522100966Siwasaki/******************************************************************************* 523100966Siwasaki * 524100966Siwasaki * FUNCTION: AcpiDmAddressSpace 525100966Siwasaki * 526100966Siwasaki * PARAMETERS: SpaceId - ID to be translated 527100966Siwasaki * 528100966Siwasaki * RETURN: None 529100966Siwasaki * 530100966Siwasaki * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword 531100966Siwasaki * 532100966Siwasaki ******************************************************************************/ 533100966Siwasaki 534100966Siwasakivoid 535100966SiwasakiAcpiDmAddressSpace ( 536100966Siwasaki UINT8 SpaceId) 537100966Siwasaki{ 538100966Siwasaki 539100966Siwasaki if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS) 540100966Siwasaki { 541100966Siwasaki if (SpaceId == 0x7F) 542100966Siwasaki { 543100966Siwasaki AcpiOsPrintf ("FFixedHW, "); 544100966Siwasaki } 545100966Siwasaki else 546100966Siwasaki { 547100966Siwasaki AcpiOsPrintf ("0x%.2X, ", SpaceId); 548100966Siwasaki } 549100966Siwasaki } 550100966Siwasaki else 551100966Siwasaki { 552100966Siwasaki AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]); 553100966Siwasaki } 554100966Siwasaki} 555100966Siwasaki 556100966Siwasaki 557100966Siwasaki/******************************************************************************* 558100966Siwasaki * 559100966Siwasaki * FUNCTION: AcpiDmRegionFlags 560100966Siwasaki * 561100966Siwasaki * PARAMETERS: Op - Object to be examined 562100966Siwasaki * 563100966Siwasaki * RETURN: None 564100966Siwasaki * 565100966Siwasaki * DESCRIPTION: Decode OperationRegion flags 566100966Siwasaki * 567100966Siwasaki ******************************************************************************/ 568100966Siwasaki 569100966Siwasakivoid 570100966SiwasakiAcpiDmRegionFlags ( 571100966Siwasaki ACPI_PARSE_OBJECT *Op) 572100966Siwasaki{ 573100966Siwasaki 574100966Siwasaki /* The next Op contains the SpaceId */ 575100966Siwasaki 576100966Siwasaki Op = AcpiPsGetDepthNext (NULL, Op); 577100966Siwasaki 578100966Siwasaki /* Mark the Op as completed */ 579100966Siwasaki 580100966Siwasaki Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 581100966Siwasaki 582100966Siwasaki AcpiOsPrintf (", "); 583117521Snjl AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer); 584100966Siwasaki} 585100966Siwasaki 586100966Siwasaki 587100966Siwasaki/******************************************************************************* 588100966Siwasaki * 589100966Siwasaki * FUNCTION: AcpiDmMatchOp 590100966Siwasaki * 591100966Siwasaki * PARAMETERS: Op - Match Object to be examined 592100966Siwasaki * 593100966Siwasaki * RETURN: None 594100966Siwasaki * 595100966Siwasaki * DESCRIPTION: Decode Match opcode operands 596100966Siwasaki * 597100966Siwasaki ******************************************************************************/ 598100966Siwasaki 599100966Siwasakivoid 600100966SiwasakiAcpiDmMatchOp ( 601100966Siwasaki ACPI_PARSE_OBJECT *Op) 602100966Siwasaki{ 603100966Siwasaki ACPI_PARSE_OBJECT *NextOp; 604100966Siwasaki 605100966Siwasaki 606100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 607100966Siwasaki NextOp = NextOp->Common.Next; 608100966Siwasaki 609100966Siwasaki if (!NextOp) 610100966Siwasaki { 611100966Siwasaki /* Handle partial tree during single-step */ 612100966Siwasaki 613100966Siwasaki return; 614100966Siwasaki } 615100966Siwasaki 616100966Siwasaki /* Mark the two nodes that contain the encoding for the match keywords */ 617100966Siwasaki 618100966Siwasaki NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP; 619100966Siwasaki 620100966Siwasaki NextOp = NextOp->Common.Next; 621100966Siwasaki NextOp = NextOp->Common.Next; 622100966Siwasaki NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP; 623100966Siwasaki} 624100966Siwasaki 625100966Siwasaki 626100966Siwasaki/******************************************************************************* 627100966Siwasaki * 628100966Siwasaki * FUNCTION: AcpiDmMatchKeyword 629100966Siwasaki * 630100966Siwasaki * PARAMETERS: Op - Match Object to be examined 631100966Siwasaki * 632100966Siwasaki * RETURN: None 633100966Siwasaki * 634100966Siwasaki * DESCRIPTION: Decode Match opcode operands 635100966Siwasaki * 636100966Siwasaki ******************************************************************************/ 637100966Siwasaki 638151937Sjkimstatic void 639100966SiwasakiAcpiDmMatchKeyword ( 640100966Siwasaki ACPI_PARSE_OBJECT *Op) 641100966Siwasaki{ 642100966Siwasaki 643167802Sjkim if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE) 644100966Siwasaki { 645100966Siwasaki AcpiOsPrintf ("/* Unknown Match Keyword encoding */"); 646100966Siwasaki } 647100966Siwasaki else 648100966Siwasaki { 649306536Sjkim AcpiOsPrintf ("%s", 650306536Sjkim AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]); 651100966Siwasaki } 652100966Siwasaki} 653100966Siwasaki 654100966Siwasaki 655100966Siwasaki/******************************************************************************* 656100966Siwasaki * 657100966Siwasaki * FUNCTION: AcpiDmDisassembleOneOp 658100966Siwasaki * 659100966Siwasaki * PARAMETERS: WalkState - Current walk info 660100966Siwasaki * Info - Parse tree walk info 661100966Siwasaki * Op - Op that is to be printed 662100966Siwasaki * 663100966Siwasaki * RETURN: None 664100966Siwasaki * 665100966Siwasaki * DESCRIPTION: Disassemble a single AML opcode 666100966Siwasaki * 667100966Siwasaki ******************************************************************************/ 668100966Siwasaki 669100966Siwasakivoid 670100966SiwasakiAcpiDmDisassembleOneOp ( 671100966Siwasaki ACPI_WALK_STATE *WalkState, 672100966Siwasaki ACPI_OP_WALK_INFO *Info, 673100966Siwasaki ACPI_PARSE_OBJECT *Op) 674100966Siwasaki{ 675100966Siwasaki const ACPI_OPCODE_INFO *OpInfo = NULL; 676100966Siwasaki UINT32 Offset; 677100966Siwasaki UINT32 Length; 678167802Sjkim ACPI_PARSE_OBJECT *Child; 679167802Sjkim ACPI_STATUS Status; 680228110Sjkim UINT8 *Aml; 681281075Sdim const AH_DEVICE_ID *IdInfo; 682100966Siwasaki 683100966Siwasaki 684100966Siwasaki if (!Op) 685100966Siwasaki { 686100966Siwasaki AcpiOsPrintf ("<NULL OP PTR>"); 687100966Siwasaki return; 688100966Siwasaki } 689100966Siwasaki 690306536Sjkim if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF) 691306536Sjkim { 692306536Sjkim return; /* ElseIf macro was already emitted */ 693306536Sjkim } 694306536Sjkim 695100966Siwasaki switch (Op->Common.DisasmOpcode) 696100966Siwasaki { 697100966Siwasaki case ACPI_DASM_MATCHOP: 698100966Siwasaki 699100966Siwasaki AcpiDmMatchKeyword (Op); 700100966Siwasaki return; 701100966Siwasaki 702167802Sjkim case ACPI_DASM_LNOT_SUFFIX: 703250838Sjkim 704281075Sdim if (!AcpiGbl_CstyleDisassembly) 705167802Sjkim { 706281075Sdim switch (Op->Common.AmlOpcode) 707281075Sdim { 708281075Sdim case AML_LEQUAL_OP: 709281075Sdim AcpiOsPrintf ("LNotEqual"); 710281075Sdim break; 711250838Sjkim 712281075Sdim case AML_LGREATER_OP: 713281075Sdim AcpiOsPrintf ("LLessEqual"); 714281075Sdim break; 715167802Sjkim 716281075Sdim case AML_LLESS_OP: 717281075Sdim AcpiOsPrintf ("LGreaterEqual"); 718281075Sdim break; 719250838Sjkim 720281075Sdim default: 721281075Sdim break; 722281075Sdim } 723281075Sdim } 724167802Sjkim 725167802Sjkim Op->Common.DisasmOpcode = 0; 726167802Sjkim Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 727167802Sjkim return; 728167802Sjkim 729100966Siwasaki default: 730100966Siwasaki break; 731100966Siwasaki } 732100966Siwasaki 733167802Sjkim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 734167802Sjkim 735117521Snjl /* The op and arguments */ 736100966Siwasaki 737100966Siwasaki switch (Op->Common.AmlOpcode) 738100966Siwasaki { 739167802Sjkim case AML_LNOT_OP: 740100966Siwasaki 741167802Sjkim Child = Op->Common.Value.Arg; 742167802Sjkim if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) || 743167802Sjkim (Child->Common.AmlOpcode == AML_LGREATER_OP) || 744167802Sjkim (Child->Common.AmlOpcode == AML_LLESS_OP)) 745167802Sjkim { 746167802Sjkim Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX; 747167802Sjkim Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX; 748167802Sjkim } 749167802Sjkim else 750167802Sjkim { 751167802Sjkim AcpiOsPrintf ("%s", OpInfo->Name); 752167802Sjkim } 753100966Siwasaki break; 754100966Siwasaki 755100966Siwasaki case AML_BYTE_OP: 756100966Siwasaki 757117521Snjl AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer); 758100966Siwasaki break; 759100966Siwasaki 760100966Siwasaki case AML_WORD_OP: 761100966Siwasaki 762100966Siwasaki if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) 763100966Siwasaki { 764281075Sdim AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer); 765100966Siwasaki } 766100966Siwasaki else 767100966Siwasaki { 768117521Snjl AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer); 769100966Siwasaki } 770100966Siwasaki break; 771100966Siwasaki 772100966Siwasaki case AML_DWORD_OP: 773100966Siwasaki 774100966Siwasaki if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID) 775100966Siwasaki { 776281075Sdim AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer); 777100966Siwasaki } 778100966Siwasaki else 779100966Siwasaki { 780117521Snjl AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer); 781100966Siwasaki } 782100966Siwasaki break; 783100966Siwasaki 784100966Siwasaki case AML_QWORD_OP: 785100966Siwasaki 786202771Sjkim AcpiOsPrintf ("0x%8.8X%8.8X", 787202771Sjkim ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); 788100966Siwasaki break; 789100966Siwasaki 790100966Siwasaki case AML_STRING_OP: 791100966Siwasaki 792252279Sjkim AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX); 793281075Sdim 794281075Sdim /* For _HID/_CID strings, attempt to output a descriptive comment */ 795281075Sdim 796281075Sdim if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING) 797281075Sdim { 798281075Sdim /* If we know about the ID, emit the description */ 799281075Sdim 800281075Sdim IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String); 801281075Sdim if (IdInfo) 802281075Sdim { 803281075Sdim AcpiOsPrintf (" /* %s */", IdInfo->Description); 804281075Sdim } 805281075Sdim } 806100966Siwasaki break; 807100966Siwasaki 808100966Siwasaki case AML_BUFFER_OP: 809100966Siwasaki /* 810241973Sjkim * Determine the type of buffer. We can have one of the following: 811100966Siwasaki * 812100966Siwasaki * 1) ResourceTemplate containing Resource Descriptors. 813100966Siwasaki * 2) Unicode String buffer 814100966Siwasaki * 3) ASCII String buffer 815100966Siwasaki * 4) Raw data buffer (if none of the above) 816100966Siwasaki * 817100966Siwasaki * Since there are no special AML opcodes to differentiate these 818100966Siwasaki * types of buffers, we have to closely look at the data in the 819100966Siwasaki * buffer to determine the type. 820100966Siwasaki */ 821228110Sjkim if (!AcpiGbl_NoResourceDisassembly) 822100966Siwasaki { 823243347Sjkim Status = AcpiDmIsResourceTemplate (WalkState, Op); 824228110Sjkim if (ACPI_SUCCESS (Status)) 825228110Sjkim { 826228110Sjkim Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE; 827228110Sjkim AcpiOsPrintf ("ResourceTemplate"); 828228110Sjkim break; 829228110Sjkim } 830228110Sjkim else if (Status == AE_AML_NO_RESOURCE_END_TAG) 831228110Sjkim { 832306536Sjkim AcpiOsPrintf ( 833306536Sjkim "/**** Is ResourceTemplate, " 834306536Sjkim "but EndTag not at buffer end ****/ "); 835228110Sjkim } 836100966Siwasaki } 837167802Sjkim 838281075Sdim if (AcpiDmIsUuidBuffer (Op)) 839167802Sjkim { 840281075Sdim Op->Common.DisasmOpcode = ACPI_DASM_UUID; 841281075Sdim AcpiOsPrintf ("ToUUID ("); 842281075Sdim } 843281075Sdim else if (AcpiDmIsUnicodeBuffer (Op)) 844281075Sdim { 845100966Siwasaki Op->Common.DisasmOpcode = ACPI_DASM_UNICODE; 846100966Siwasaki AcpiOsPrintf ("Unicode ("); 847100966Siwasaki } 848100966Siwasaki else if (AcpiDmIsStringBuffer (Op)) 849100966Siwasaki { 850100966Siwasaki Op->Common.DisasmOpcode = ACPI_DASM_STRING; 851100966Siwasaki AcpiOsPrintf ("Buffer"); 852100966Siwasaki } 853239340Sjkim else if (AcpiDmIsPldBuffer (Op)) 854239340Sjkim { 855239340Sjkim Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD; 856281075Sdim AcpiOsPrintf ("ToPLD ("); 857239340Sjkim } 858100966Siwasaki else 859100966Siwasaki { 860100966Siwasaki Op->Common.DisasmOpcode = ACPI_DASM_BUFFER; 861100966Siwasaki AcpiOsPrintf ("Buffer"); 862100966Siwasaki } 863100966Siwasaki break; 864100966Siwasaki 865100966Siwasaki case AML_INT_NAMEPATH_OP: 866100966Siwasaki 867100966Siwasaki AcpiDmNamestring (Op->Common.Value.Name); 868100966Siwasaki break; 869100966Siwasaki 870100966Siwasaki case AML_INT_NAMEDFIELD_OP: 871100966Siwasaki 872193267Sjkim Length = AcpiDmDumpName (Op->Named.Name); 873209746Sjkim AcpiOsPrintf (",%*.s %u", (unsigned) (5 - Length), " ", 874151937Sjkim (UINT32) Op->Common.Value.Integer); 875100966Siwasaki AcpiDmCommaIfFieldMember (Op); 876100966Siwasaki 877117521Snjl Info->BitOffset += (UINT32) Op->Common.Value.Integer; 878100966Siwasaki break; 879100966Siwasaki 880100966Siwasaki case AML_INT_RESERVEDFIELD_OP: 881100966Siwasaki 882100966Siwasaki /* Offset() -- Must account for previous offsets */ 883100966Siwasaki 884117521Snjl Offset = (UINT32) Op->Common.Value.Integer; 885100966Siwasaki Info->BitOffset += Offset; 886100966Siwasaki 887100966Siwasaki if (Info->BitOffset % 8 == 0) 888100966Siwasaki { 889228110Sjkim AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset)); 890100966Siwasaki } 891100966Siwasaki else 892100966Siwasaki { 893209746Sjkim AcpiOsPrintf (" , %u", Offset); 894100966Siwasaki } 895100966Siwasaki 896100966Siwasaki AcpiDmCommaIfFieldMember (Op); 897100966Siwasaki break; 898100966Siwasaki 899100966Siwasaki case AML_INT_ACCESSFIELD_OP: 900228110Sjkim case AML_INT_EXTACCESSFIELD_OP: 901100966Siwasaki 902228110Sjkim AcpiOsPrintf ("AccessAs (%s, ", 903228110Sjkim AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]); 904100966Siwasaki 905228110Sjkim AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8)); 906228110Sjkim 907228110Sjkim if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP) 908228110Sjkim { 909306536Sjkim AcpiOsPrintf (" (0x%2.2X)", (unsigned) 910306536Sjkim ((Op->Common.Value.Integer >> 16) & 0xFF)); 911228110Sjkim } 912228110Sjkim 913107325Siwasaki AcpiOsPrintf (")"); 914100966Siwasaki AcpiDmCommaIfFieldMember (Op); 915100966Siwasaki break; 916100966Siwasaki 917228110Sjkim case AML_INT_CONNECTION_OP: 918228110Sjkim /* 919228110Sjkim * Two types of Connection() - one with a buffer object, the 920228110Sjkim * other with a namestring that points to a buffer object. 921228110Sjkim */ 922228110Sjkim AcpiOsPrintf ("Connection ("); 923228110Sjkim Child = Op->Common.Value.Arg; 924228110Sjkim 925228110Sjkim if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP) 926228110Sjkim { 927228110Sjkim AcpiOsPrintf ("\n"); 928228110Sjkim 929228110Sjkim Aml = Child->Named.Data; 930228110Sjkim Length = (UINT32) Child->Common.Value.Integer; 931228110Sjkim 932228110Sjkim Info->Level += 1; 933281075Sdim Info->MappingOp = Op; 934228110Sjkim Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE; 935281075Sdim 936228110Sjkim AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length); 937228110Sjkim 938228110Sjkim Info->Level -= 1; 939228110Sjkim AcpiDmIndent (Info->Level); 940228110Sjkim } 941228110Sjkim else 942228110Sjkim { 943228110Sjkim AcpiDmNamestring (Child->Common.Value.Name); 944228110Sjkim } 945228110Sjkim 946228110Sjkim AcpiOsPrintf (")"); 947228110Sjkim AcpiDmCommaIfFieldMember (Op); 948228110Sjkim AcpiOsPrintf ("\n"); 949228110Sjkim 950228110Sjkim Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */ 951228110Sjkim Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 952228110Sjkim break; 953228110Sjkim 954100966Siwasaki case AML_INT_BYTELIST_OP: 955100966Siwasaki 956100966Siwasaki AcpiDmByteList (Info, Op); 957100966Siwasaki break; 958100966Siwasaki 959100966Siwasaki case AML_INT_METHODCALL_OP: 960100966Siwasaki 961100966Siwasaki Op = AcpiPsGetDepthNext (NULL, Op); 962100966Siwasaki Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 963100966Siwasaki 964100966Siwasaki AcpiDmNamestring (Op->Common.Value.Name); 965100966Siwasaki break; 966100966Siwasaki 967306536Sjkim case AML_ELSE_OP: 968306536Sjkim 969306536Sjkim AcpiDmConvertToElseIf (Op); 970306536Sjkim break; 971306536Sjkim 972306536Sjkim case AML_EXTERNAL_OP: 973306536Sjkim 974306536Sjkim if (AcpiGbl_DmEmitExternalOpcodes) 975306536Sjkim { 976306536Sjkim AcpiOsPrintf ("/* Opcode 0x15 */ "); 977306536Sjkim 978306536Sjkim /* Fallthrough */ 979306536Sjkim } 980306536Sjkim else 981306536Sjkim { 982306536Sjkim break; 983306536Sjkim } 984306536Sjkim 985100966Siwasaki default: 986100966Siwasaki 987100966Siwasaki /* Just get the opcode name and print it */ 988100966Siwasaki 989100966Siwasaki AcpiOsPrintf ("%s", OpInfo->Name); 990100966Siwasaki 991100966Siwasaki 992102550Siwasaki#ifdef ACPI_DEBUGGER 993100966Siwasaki 994100966Siwasaki if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) && 995100966Siwasaki (WalkState) && 996100966Siwasaki (WalkState->Results) && 997167802Sjkim (WalkState->ResultCount)) 998100966Siwasaki { 999306536Sjkim AcpiDbDecodeInternalObject ( 1000151937Sjkim WalkState->Results->Results.ObjDesc [ 1001167802Sjkim (WalkState->ResultCount - 1) % 1002167802Sjkim ACPI_RESULTS_FRAME_OBJ_NUM]); 1003100966Siwasaki } 1004100966Siwasaki#endif 1005167802Sjkim 1006100966Siwasaki break; 1007100966Siwasaki } 1008100966Siwasaki} 1009100966Siwasaki 1010306536Sjkim 1011306536Sjkim/******************************************************************************* 1012306536Sjkim * 1013306536Sjkim * FUNCTION: AcpiDmConvertToElseIf 1014306536Sjkim * 1015306536Sjkim * PARAMETERS: OriginalElseOp - ELSE Object to be examined 1016306536Sjkim * 1017306536Sjkim * RETURN: None. Emits either an "Else" or an "ElseIf" ASL operator. 1018306536Sjkim * 1019306536Sjkim * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf 1020306536Sjkim * 1021306536Sjkim * EXAMPLE: 1022306536Sjkim * 1023306536Sjkim * This If..Else..If nested sequence: 1024306536Sjkim * 1025306536Sjkim * If (Arg0 == 1) 1026306536Sjkim * { 1027306536Sjkim * Local0 = 4 1028306536Sjkim * } 1029306536Sjkim * Else 1030306536Sjkim * { 1031306536Sjkim * If (Arg0 == 2) 1032306536Sjkim * { 1033306536Sjkim * Local0 = 5 1034306536Sjkim * } 1035306536Sjkim * } 1036306536Sjkim * 1037306536Sjkim * Is converted to this simpler If..ElseIf sequence: 1038306536Sjkim * 1039306536Sjkim * If (Arg0 == 1) 1040306536Sjkim * { 1041306536Sjkim * Local0 = 4 1042306536Sjkim * } 1043306536Sjkim * ElseIf (Arg0 == 2) 1044306536Sjkim * { 1045306536Sjkim * Local0 = 5 1046306536Sjkim * } 1047306536Sjkim * 1048306536Sjkim * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL 1049306536Sjkim * macro that emits an Else opcode followed by an If opcode. This function 1050306536Sjkim * reverses these AML sequences back to an ElseIf macro where possible. This 1051306536Sjkim * can make the disassembled ASL code simpler and more like the original code. 1052306536Sjkim * 1053306536Sjkim ******************************************************************************/ 1054306536Sjkim 1055306536Sjkimstatic void 1056306536SjkimAcpiDmConvertToElseIf ( 1057306536Sjkim ACPI_PARSE_OBJECT *OriginalElseOp) 1058306536Sjkim{ 1059306536Sjkim ACPI_PARSE_OBJECT *IfOp; 1060306536Sjkim ACPI_PARSE_OBJECT *ElseOp; 1061306536Sjkim 1062306536Sjkim 1063306536Sjkim /* 1064306536Sjkim * To be able to perform the conversion, two conditions must be satisfied: 1065306536Sjkim * 1) The first child of the Else must be an If statement. 1066306536Sjkim * 2) The If block can only be followed by an Else block and these must 1067306536Sjkim * be the only blocks under the original Else. 1068306536Sjkim */ 1069306536Sjkim IfOp = OriginalElseOp->Common.Value.Arg; 1070306536Sjkim if (!IfOp || 1071306536Sjkim (IfOp->Common.AmlOpcode != AML_IF_OP) || 1072306536Sjkim (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP))) 1073306536Sjkim { 1074306536Sjkim /* Not an Else..If sequence, cannot convert to ElseIf */ 1075306536Sjkim 1076306536Sjkim AcpiOsPrintf ("%s", "Else"); 1077306536Sjkim return; 1078306536Sjkim } 1079306536Sjkim 1080306536Sjkim /* Emit ElseIf, mark the IF as now an ELSEIF */ 1081306536Sjkim 1082306536Sjkim AcpiOsPrintf ("%s", "ElseIf"); 1083306536Sjkim IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF; 1084306536Sjkim 1085306536Sjkim /* The IF parent will now be the same as the original ELSE parent */ 1086306536Sjkim 1087306536Sjkim IfOp->Common.Parent = OriginalElseOp->Common.Parent; 1088306536Sjkim 1089306536Sjkim /* 1090306536Sjkim * Update the NEXT pointers to restructure the parse tree, essentially 1091306536Sjkim * promoting an If..Else block up to the same level as the original 1092306536Sjkim * Else. 1093306536Sjkim * 1094306536Sjkim * Check if the IF has a corresponding ELSE peer 1095306536Sjkim */ 1096306536Sjkim ElseOp = IfOp->Common.Next; 1097306536Sjkim if (ElseOp && 1098306536Sjkim (ElseOp->Common.AmlOpcode == AML_ELSE_OP)) 1099306536Sjkim { 1100306536Sjkim /* If an ELSE matches the IF, promote it also */ 1101306536Sjkim 1102306536Sjkim ElseOp->Common.Parent = OriginalElseOp->Common.Parent; 1103306536Sjkim ElseOp->Common.Next = OriginalElseOp->Common.Next; 1104306536Sjkim } 1105306536Sjkim else 1106306536Sjkim { 1107306536Sjkim /* Otherwise, set the IF NEXT to the original ELSE NEXT */ 1108306536Sjkim 1109306536Sjkim IfOp->Common.Next = OriginalElseOp->Common.Next; 1110306536Sjkim } 1111306536Sjkim 1112306536Sjkim /* Detach the child IF block from the original ELSE */ 1113306536Sjkim 1114306536Sjkim OriginalElseOp->Common.Value.Arg = NULL; 1115306536Sjkim 1116306536Sjkim /* Ignore the original ELSE from now on */ 1117306536Sjkim 1118306536Sjkim OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 1119306536Sjkim OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX; 1120306536Sjkim 1121306536Sjkim /* Insert IF (now ELSEIF) as next peer of the original ELSE */ 1122306536Sjkim 1123306536Sjkim OriginalElseOp->Common.Next = IfOp; 1124306536Sjkim} 1125