1af051161SJung-uk Kim /****************************************************************************** 2af051161SJung-uk Kim * 3af051161SJung-uk Kim * Module Name: adwalk - Disassembler routines for switch statements 4af051161SJung-uk Kim * 5af051161SJung-uk Kim *****************************************************************************/ 6af051161SJung-uk Kim 7af051161SJung-uk Kim /****************************************************************************** 8af051161SJung-uk Kim * 9af051161SJung-uk Kim * 1. Copyright Notice 10af051161SJung-uk Kim * 11*804fe266SJung-uk Kim * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 12af051161SJung-uk Kim * All rights reserved. 13af051161SJung-uk Kim * 14af051161SJung-uk Kim * 2. License 15af051161SJung-uk Kim * 16af051161SJung-uk Kim * 2.1. This is your license from Intel Corp. under its intellectual property 17af051161SJung-uk Kim * rights. You may have additional license terms from the party that provided 18af051161SJung-uk Kim * you this software, covering your right to use that party's intellectual 19af051161SJung-uk Kim * property rights. 20af051161SJung-uk Kim * 21af051161SJung-uk Kim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22af051161SJung-uk Kim * copy of the source code appearing in this file ("Covered Code") an 23af051161SJung-uk Kim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24af051161SJung-uk Kim * base code distributed originally by Intel ("Original Intel Code") to copy, 25af051161SJung-uk Kim * make derivatives, distribute, use and display any portion of the Covered 26af051161SJung-uk Kim * Code in any form, with the right to sublicense such rights; and 27af051161SJung-uk Kim * 28af051161SJung-uk Kim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29af051161SJung-uk Kim * license (with the right to sublicense), under only those claims of Intel 30af051161SJung-uk Kim * patents that are infringed by the Original Intel Code, to make, use, sell, 31af051161SJung-uk Kim * offer to sell, and import the Covered Code and derivative works thereof 32af051161SJung-uk Kim * solely to the minimum extent necessary to exercise the above copyright 33af051161SJung-uk Kim * license, and in no event shall the patent license extend to any additions 34af051161SJung-uk Kim * to or modifications of the Original Intel Code. No other license or right 35af051161SJung-uk Kim * is granted directly or by implication, estoppel or otherwise; 36af051161SJung-uk Kim * 37af051161SJung-uk Kim * The above copyright and patent license is granted only if the following 38af051161SJung-uk Kim * conditions are met: 39af051161SJung-uk Kim * 40af051161SJung-uk Kim * 3. Conditions 41af051161SJung-uk Kim * 42af051161SJung-uk Kim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43af051161SJung-uk Kim * Redistribution of source code of any substantial portion of the Covered 44af051161SJung-uk Kim * Code or modification with rights to further distribute source must include 45af051161SJung-uk Kim * the above Copyright Notice, the above License, this list of Conditions, 46af051161SJung-uk Kim * and the following Disclaimer and Export Compliance provision. In addition, 47af051161SJung-uk Kim * Licensee must cause all Covered Code to which Licensee contributes to 48af051161SJung-uk Kim * contain a file documenting the changes Licensee made to create that Covered 49af051161SJung-uk Kim * Code and the date of any change. Licensee must include in that file the 50af051161SJung-uk Kim * documentation of any changes made by any predecessor Licensee. Licensee 51af051161SJung-uk Kim * must include a prominent statement that the modification is derived, 52af051161SJung-uk Kim * directly or indirectly, from Original Intel Code. 53af051161SJung-uk Kim * 54af051161SJung-uk Kim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55af051161SJung-uk Kim * Redistribution of source code of any substantial portion of the Covered 56af051161SJung-uk Kim * Code or modification without rights to further distribute source must 57af051161SJung-uk Kim * include the following Disclaimer and Export Compliance provision in the 58af051161SJung-uk Kim * documentation and/or other materials provided with distribution. In 59af051161SJung-uk Kim * addition, Licensee may not authorize further sublicense of source of any 60af051161SJung-uk Kim * portion of the Covered Code, and must include terms to the effect that the 61af051161SJung-uk Kim * license from Licensee to its licensee is limited to the intellectual 62af051161SJung-uk Kim * property embodied in the software Licensee provides to its licensee, and 63af051161SJung-uk Kim * not to intellectual property embodied in modifications its licensee may 64af051161SJung-uk Kim * make. 65af051161SJung-uk Kim * 66af051161SJung-uk Kim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67af051161SJung-uk Kim * substantial portion of the Covered Code or modification must reproduce the 68af051161SJung-uk Kim * above Copyright Notice, and the following Disclaimer and Export Compliance 69af051161SJung-uk Kim * provision in the documentation and/or other materials provided with the 70af051161SJung-uk Kim * distribution. 71af051161SJung-uk Kim * 72af051161SJung-uk Kim * 3.4. Intel retains all right, title, and interest in and to the Original 73af051161SJung-uk Kim * Intel Code. 74af051161SJung-uk Kim * 75af051161SJung-uk Kim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76af051161SJung-uk Kim * Intel shall be used in advertising or otherwise to promote the sale, use or 77af051161SJung-uk Kim * other dealings in products derived from or relating to the Covered Code 78af051161SJung-uk Kim * without prior written authorization from Intel. 79af051161SJung-uk Kim * 80af051161SJung-uk Kim * 4. Disclaimer and Export Compliance 81af051161SJung-uk Kim * 82af051161SJung-uk Kim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83af051161SJung-uk Kim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84af051161SJung-uk Kim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85af051161SJung-uk Kim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86af051161SJung-uk Kim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87af051161SJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88af051161SJung-uk Kim * PARTICULAR PURPOSE. 89af051161SJung-uk Kim * 90af051161SJung-uk Kim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91af051161SJung-uk Kim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92af051161SJung-uk Kim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93af051161SJung-uk Kim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94af051161SJung-uk Kim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95af051161SJung-uk Kim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96af051161SJung-uk Kim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97af051161SJung-uk Kim * LIMITED REMEDY. 98af051161SJung-uk Kim * 99af051161SJung-uk Kim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100af051161SJung-uk Kim * software or system incorporating such software without first obtaining any 101af051161SJung-uk Kim * required license or other approval from the U. S. Department of Commerce or 102af051161SJung-uk Kim * any other agency or department of the United States Government. In the 103af051161SJung-uk Kim * event Licensee exports any such software from the United States or 104af051161SJung-uk Kim * re-exports any such software from a foreign destination, Licensee shall 105af051161SJung-uk Kim * ensure that the distribution and export/re-export of the software is in 106af051161SJung-uk Kim * compliance with all laws, regulations, orders, or other restrictions of the 107af051161SJung-uk Kim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108af051161SJung-uk Kim * any of its subsidiaries will export/re-export any technical data, process, 109af051161SJung-uk Kim * software, or service, directly or indirectly, to any country for which the 110af051161SJung-uk Kim * United States government or any agency thereof requires an export license, 111af051161SJung-uk Kim * other governmental approval, or letter of assurance, without first obtaining 112af051161SJung-uk Kim * such license, approval or letter. 113af051161SJung-uk Kim * 114af051161SJung-uk Kim ***************************************************************************** 115af051161SJung-uk Kim * 116af051161SJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the 117af051161SJung-uk Kim * following license: 118af051161SJung-uk Kim * 119af051161SJung-uk Kim * Redistribution and use in source and binary forms, with or without 120af051161SJung-uk Kim * modification, are permitted provided that the following conditions 121af051161SJung-uk Kim * are met: 122af051161SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 123af051161SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 124af051161SJung-uk Kim * without modification. 125af051161SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126af051161SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 127af051161SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 128af051161SJung-uk Kim * including a substantially similar Disclaimer requirement for further 129af051161SJung-uk Kim * binary redistribution. 130af051161SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 131af051161SJung-uk Kim * of any contributors may be used to endorse or promote products derived 132af051161SJung-uk Kim * from this software without specific prior written permission. 133af051161SJung-uk Kim * 134af051161SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135af051161SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136af051161SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137af051161SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138af051161SJung-uk Kim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139af051161SJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140af051161SJung-uk Kim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141af051161SJung-uk Kim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142af051161SJung-uk Kim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143af051161SJung-uk Kim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144af051161SJung-uk Kim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145af051161SJung-uk Kim * 146af051161SJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the 147af051161SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 148af051161SJung-uk Kim * Software Foundation. 149af051161SJung-uk Kim * 150af051161SJung-uk Kim *****************************************************************************/ 151af051161SJung-uk Kim 152af051161SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 153af051161SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 154af051161SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 155af051161SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 156af051161SJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h> 157af051161SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h> 158af051161SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h> 159af051161SJung-uk Kim #include <contrib/dev/acpica/include/acapps.h> 160af051161SJung-uk Kim 161af051161SJung-uk Kim 162af051161SJung-uk Kim #define _COMPONENT ACPI_CA_DISASSEMBLER 163af051161SJung-uk Kim ACPI_MODULE_NAME ("dmswitch") 164af051161SJung-uk Kim 165af051161SJung-uk Kim static BOOLEAN 166af051161SJung-uk Kim AcpiDmIsSwitchBlock ( 167af051161SJung-uk Kim ACPI_PARSE_OBJECT *Op, 168af051161SJung-uk Kim char **Temp); 169af051161SJung-uk Kim 170af051161SJung-uk Kim static BOOLEAN 171af051161SJung-uk Kim AcpiDmIsCaseBlock ( 172af051161SJung-uk Kim ACPI_PARSE_OBJECT *Op); 173af051161SJung-uk Kim 174af051161SJung-uk Kim 175af051161SJung-uk Kim /******************************************************************************* 176af051161SJung-uk Kim * 177af051161SJung-uk Kim * FUNCTION: AcpiDmProcessSwitch 178af051161SJung-uk Kim * 179af051161SJung-uk Kim * PARAMETERS: Op - Object to be examined 180af051161SJung-uk Kim * 181af051161SJung-uk Kim * RETURN: ACPI_STATUS 182af051161SJung-uk Kim * 183af051161SJung-uk Kim * DESCRIPTION: Walk function to create a list of all temporary (_T_) objects. 184af051161SJung-uk Kim * If a While loop is found that can be converted to a Switch, do 185af051161SJung-uk Kim * the conversion, remove the temporary name from the list, and 186af051161SJung-uk Kim * mark the parse op with an IGNORE flag. 187af051161SJung-uk Kim * 188af051161SJung-uk Kim ******************************************************************************/ 189af051161SJung-uk Kim 190af051161SJung-uk Kim ACPI_STATUS 191af051161SJung-uk Kim AcpiDmProcessSwitch ( 192af051161SJung-uk Kim ACPI_PARSE_OBJECT *Op) 193af051161SJung-uk Kim { 194af051161SJung-uk Kim char *Temp = NULL; 195af051161SJung-uk Kim ACPI_PARSE_OBJECT_LIST *NewTemp; 196af051161SJung-uk Kim ACPI_PARSE_OBJECT_LIST *Current; 197af051161SJung-uk Kim ACPI_PARSE_OBJECT_LIST *Previous; 198af051161SJung-uk Kim BOOLEAN FoundTemp = FALSE; 199af051161SJung-uk Kim 200af051161SJung-uk Kim 201af051161SJung-uk Kim switch (Op->Common.AmlOpcode) 202af051161SJung-uk Kim { 203af051161SJung-uk Kim case AML_NAME_OP: 204af051161SJung-uk Kim 205af051161SJung-uk Kim Temp = (char *) (&Op->Named.Name); 206af051161SJung-uk Kim 207af051161SJung-uk Kim if (!strncmp(Temp, "_T_", 3)) 208af051161SJung-uk Kim { 209af051161SJung-uk Kim /* Allocate and init a new Temp List node */ 210af051161SJung-uk Kim 211af051161SJung-uk Kim NewTemp = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PARSE_OBJECT_LIST)); 212af051161SJung-uk Kim if (!NewTemp) 213af051161SJung-uk Kim { 214af051161SJung-uk Kim return (AE_NO_MEMORY); 215af051161SJung-uk Kim } 216af051161SJung-uk Kim 217af051161SJung-uk Kim if (AcpiGbl_TempListHead) 218af051161SJung-uk Kim { 219af051161SJung-uk Kim Current = AcpiGbl_TempListHead; 220af051161SJung-uk Kim AcpiGbl_TempListHead = NewTemp; 221af051161SJung-uk Kim AcpiGbl_TempListHead->Op = Op; 222af051161SJung-uk Kim AcpiGbl_TempListHead->Next = Current; 223af051161SJung-uk Kim } 224af051161SJung-uk Kim else 225af051161SJung-uk Kim { 226af051161SJung-uk Kim AcpiGbl_TempListHead = NewTemp; 227af051161SJung-uk Kim AcpiGbl_TempListHead->Op = Op; 228af051161SJung-uk Kim AcpiGbl_TempListHead->Next = NULL; 229af051161SJung-uk Kim } 230af051161SJung-uk Kim } 231af051161SJung-uk Kim break; 232af051161SJung-uk Kim 233af051161SJung-uk Kim case AML_WHILE_OP: 234af051161SJung-uk Kim 235af051161SJung-uk Kim if (!AcpiDmIsSwitchBlock (Op, &Temp)) 236af051161SJung-uk Kim { 237af051161SJung-uk Kim break; 238af051161SJung-uk Kim } 239af051161SJung-uk Kim 240af051161SJung-uk Kim /* Found a Switch */ 241af051161SJung-uk Kim 242af051161SJung-uk Kim Op->Common.DisasmOpcode = ACPI_DASM_SWITCH; 243af051161SJung-uk Kim 244af051161SJung-uk Kim Previous = Current = AcpiGbl_TempListHead; 245af051161SJung-uk Kim while (Current) 246af051161SJung-uk Kim { 247af051161SJung-uk Kim /* Note, if we get here Temp is not NULL */ 248af051161SJung-uk Kim 249af051161SJung-uk Kim if (!strncmp(Temp, (char *) (&Current->Op->Named.Name), 4)) 250af051161SJung-uk Kim { 251af051161SJung-uk Kim /* Match found. Ignore disassembly */ 252af051161SJung-uk Kim 253af051161SJung-uk Kim Current->Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 254af051161SJung-uk Kim 255af051161SJung-uk Kim /* Remove from list */ 256af051161SJung-uk Kim 257af051161SJung-uk Kim if (Current == AcpiGbl_TempListHead) 258af051161SJung-uk Kim { 259af051161SJung-uk Kim AcpiGbl_TempListHead = Current->Next; 260af051161SJung-uk Kim } 261af051161SJung-uk Kim else 262af051161SJung-uk Kim { 263af051161SJung-uk Kim Previous->Next = Current->Next; 264af051161SJung-uk Kim } 265af051161SJung-uk Kim 266af051161SJung-uk Kim Current->Op = NULL; 267af051161SJung-uk Kim Current->Next = NULL; 268af051161SJung-uk Kim ACPI_FREE (Current); 269af051161SJung-uk Kim FoundTemp = TRUE; 270af051161SJung-uk Kim break; 271af051161SJung-uk Kim } 272af051161SJung-uk Kim 273af051161SJung-uk Kim Previous = Current; 274af051161SJung-uk Kim Current = Current->Next; 275af051161SJung-uk Kim } 276af051161SJung-uk Kim 277af051161SJung-uk Kim if (!FoundTemp) 278af051161SJung-uk Kim { 279af051161SJung-uk Kim fprintf (stderr, 280af051161SJung-uk Kim "Warning: Declaration for temp name %.4s not found\n", Temp); 281af051161SJung-uk Kim } 282af051161SJung-uk Kim break; 283af051161SJung-uk Kim 284af051161SJung-uk Kim default: 285af051161SJung-uk Kim break; 286af051161SJung-uk Kim } 287af051161SJung-uk Kim 288af051161SJung-uk Kim return (AE_OK); 289af051161SJung-uk Kim } 290af051161SJung-uk Kim 291af051161SJung-uk Kim 292af051161SJung-uk Kim /******************************************************************************* 293af051161SJung-uk Kim * 294af051161SJung-uk Kim * FUNCTION: AcpiDmClearTempList 295af051161SJung-uk Kim * 296af051161SJung-uk Kim * PARAMETERS: None 297af051161SJung-uk Kim * 298af051161SJung-uk Kim * RETURN: None 299af051161SJung-uk Kim * 300af051161SJung-uk Kim * DESCRIPTION: Removes any remaining temporary objects from global list and 301af051161SJung-uk Kim * frees 302af051161SJung-uk Kim * 303af051161SJung-uk Kim ******************************************************************************/ 304af051161SJung-uk Kim 305af051161SJung-uk Kim void 306af051161SJung-uk Kim AcpiDmClearTempList ( 307af051161SJung-uk Kim void) 308af051161SJung-uk Kim { 309af051161SJung-uk Kim ACPI_PARSE_OBJECT_LIST *Current; 310af051161SJung-uk Kim 311af051161SJung-uk Kim 312af051161SJung-uk Kim while (AcpiGbl_TempListHead) 313af051161SJung-uk Kim { 314af051161SJung-uk Kim Current = AcpiGbl_TempListHead; 315af051161SJung-uk Kim AcpiGbl_TempListHead = AcpiGbl_TempListHead->Next; 316af051161SJung-uk Kim Current->Op = NULL; 317af051161SJung-uk Kim Current->Next = NULL; 318af051161SJung-uk Kim ACPI_FREE (Current); 319af051161SJung-uk Kim } 320af051161SJung-uk Kim } 321af051161SJung-uk Kim 322af051161SJung-uk Kim 323af051161SJung-uk Kim /******************************************************************************* 324af051161SJung-uk Kim * 325af051161SJung-uk Kim * FUNCTION: AcpiDmIsSwitchBlock 326af051161SJung-uk Kim * 327af051161SJung-uk Kim * PARAMETERS: Op - While Object 32890b566fdSJung-uk Kim * Temp - Where the compiler temp name is returned 32990b566fdSJung-uk Kim * (_T_x) 330af051161SJung-uk Kim * 331af051161SJung-uk Kim * RETURN: TRUE if While block can be converted to a Switch/Case block 332af051161SJung-uk Kim * 333af051161SJung-uk Kim * DESCRIPTION: Determines if While block is a Switch/Case statement. Modifies 334af051161SJung-uk Kim * parse tree to allow for Switch/Case disassembly during walk. 335af051161SJung-uk Kim * 336af051161SJung-uk Kim * EXAMPLE: Example of parse tree to be converted 337af051161SJung-uk Kim * 338af051161SJung-uk Kim * While 339af051161SJung-uk Kim * One 340af051161SJung-uk Kim * Store 341af051161SJung-uk Kim * ByteConst 342af051161SJung-uk Kim * -NamePath- 343af051161SJung-uk Kim * If 344af051161SJung-uk Kim * LEqual 345af051161SJung-uk Kim * -NamePath- 346af051161SJung-uk Kim * Zero 347af051161SJung-uk Kim * Return 348af051161SJung-uk Kim * One 349af051161SJung-uk Kim * Else 350af051161SJung-uk Kim * Return 351af051161SJung-uk Kim * WordConst 352af051161SJung-uk Kim * Break 353af051161SJung-uk Kim * 354af051161SJung-uk Kim ******************************************************************************/ 355af051161SJung-uk Kim 356af051161SJung-uk Kim BOOLEAN 357af051161SJung-uk Kim AcpiDmIsSwitchBlock ( 358af051161SJung-uk Kim ACPI_PARSE_OBJECT *Op, 359af051161SJung-uk Kim char **Temp) 360af051161SJung-uk Kim { 361af051161SJung-uk Kim ACPI_PARSE_OBJECT *OneOp; 362af051161SJung-uk Kim ACPI_PARSE_OBJECT *StoreOp; 363af051161SJung-uk Kim ACPI_PARSE_OBJECT *NamePathOp; 364af051161SJung-uk Kim ACPI_PARSE_OBJECT *PredicateOp; 365af051161SJung-uk Kim ACPI_PARSE_OBJECT *CurrentOp; 366af051161SJung-uk Kim ACPI_PARSE_OBJECT *TempOp; 367af051161SJung-uk Kim 368af051161SJung-uk Kim 369af051161SJung-uk Kim /* Check for One Op Predicate */ 370af051161SJung-uk Kim 371af051161SJung-uk Kim OneOp = AcpiPsGetArg (Op, 0); 372af051161SJung-uk Kim if (!OneOp || (OneOp->Common.AmlOpcode != AML_ONE_OP)) 373af051161SJung-uk Kim { 374af051161SJung-uk Kim return (FALSE); 375af051161SJung-uk Kim } 376af051161SJung-uk Kim 377af051161SJung-uk Kim /* Check for Store Op */ 378af051161SJung-uk Kim 379af051161SJung-uk Kim StoreOp = OneOp->Common.Next; 380af051161SJung-uk Kim if (!StoreOp || (StoreOp->Common.AmlOpcode != AML_STORE_OP)) 381af051161SJung-uk Kim { 382af051161SJung-uk Kim return (FALSE); 383af051161SJung-uk Kim } 384af051161SJung-uk Kim 385af051161SJung-uk Kim /* Check for Name Op with _T_ string */ 386af051161SJung-uk Kim 387af051161SJung-uk Kim NamePathOp = AcpiPsGetArg (StoreOp, 1); 388af051161SJung-uk Kim if (!NamePathOp || 389af051161SJung-uk Kim (NamePathOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)) 390af051161SJung-uk Kim { 391af051161SJung-uk Kim return (FALSE); 392af051161SJung-uk Kim } 393af051161SJung-uk Kim 394af051161SJung-uk Kim if (strncmp ((char *) (NamePathOp->Common.Value.Name), "_T_", 3)) 395af051161SJung-uk Kim { 396af051161SJung-uk Kim return (FALSE); 397af051161SJung-uk Kim } 398af051161SJung-uk Kim 399af051161SJung-uk Kim *Temp = (char *) (NamePathOp->Common.Value.Name); 400af051161SJung-uk Kim 401af051161SJung-uk Kim /* This is a Switch/Case control block */ 402af051161SJung-uk Kim 403af051161SJung-uk Kim /* Ignore the One Op Predicate */ 404af051161SJung-uk Kim 405af051161SJung-uk Kim OneOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 406af051161SJung-uk Kim 407af051161SJung-uk Kim /* Ignore the Store Op, but not the children */ 408af051161SJung-uk Kim 409af051161SJung-uk Kim StoreOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE; 410af051161SJung-uk Kim 411af051161SJung-uk Kim /* 412af051161SJung-uk Kim * First arg of Store Op is the Switch condition. 413af051161SJung-uk Kim * Mark it as a Switch predicate and as a parameter list for paren 414af051161SJung-uk Kim * closing and correct indentation. 415af051161SJung-uk Kim */ 416af051161SJung-uk Kim PredicateOp = AcpiPsGetArg (StoreOp, 0); 417af051161SJung-uk Kim PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE; 418af051161SJung-uk Kim PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 419af051161SJung-uk Kim 420af051161SJung-uk Kim /* Ignore the Name Op */ 421af051161SJung-uk Kim 422af051161SJung-uk Kim NamePathOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE; 423af051161SJung-uk Kim 424af051161SJung-uk Kim /* Remaining opcodes are the Case statements (If/ElseIf's) */ 425af051161SJung-uk Kim 426af051161SJung-uk Kim CurrentOp = StoreOp->Common.Next; 427af051161SJung-uk Kim while (AcpiDmIsCaseBlock (CurrentOp)) 428af051161SJung-uk Kim { 429af051161SJung-uk Kim /* Block is a Case structure */ 430af051161SJung-uk Kim 431af051161SJung-uk Kim if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP) 432af051161SJung-uk Kim { 433af051161SJung-uk Kim /* ElseIf */ 434af051161SJung-uk Kim 435af051161SJung-uk Kim CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE; 436af051161SJung-uk Kim CurrentOp = AcpiPsGetArg (CurrentOp, 0); 437af051161SJung-uk Kim } 438af051161SJung-uk Kim 439af051161SJung-uk Kim /* If */ 440af051161SJung-uk Kim 441af051161SJung-uk Kim CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE; 442af051161SJung-uk Kim 443af051161SJung-uk Kim /* 444af051161SJung-uk Kim * Mark the parse tree for Case disassembly. There are two 445af051161SJung-uk Kim * types of Case statements. The first type of statement begins with 446af051161SJung-uk Kim * an LEqual. The second starts with an LNot and uses a Match statement 447af051161SJung-uk Kim * on a Package of constants. 448af051161SJung-uk Kim */ 449af051161SJung-uk Kim TempOp = AcpiPsGetArg (CurrentOp, 0); 450af051161SJung-uk Kim switch (TempOp->Common.AmlOpcode) 451af051161SJung-uk Kim { 452af051161SJung-uk Kim case (AML_LOGICAL_EQUAL_OP): 453af051161SJung-uk Kim 454af051161SJung-uk Kim /* Ignore just the LEqual Op */ 455af051161SJung-uk Kim 456af051161SJung-uk Kim TempOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE; 457af051161SJung-uk Kim 458af051161SJung-uk Kim /* Ignore the NamePath Op */ 459af051161SJung-uk Kim 460af051161SJung-uk Kim TempOp = AcpiPsGetArg (TempOp, 0); 461af051161SJung-uk Kim TempOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE; 462af051161SJung-uk Kim 463af051161SJung-uk Kim /* 464af051161SJung-uk Kim * Second arg of LEqual will be the Case predicate. 465af051161SJung-uk Kim * Mark it as a predicate and also as a parameter list for paren 466af051161SJung-uk Kim * closing and correct indentation. 467af051161SJung-uk Kim */ 468af051161SJung-uk Kim PredicateOp = TempOp->Common.Next; 469af051161SJung-uk Kim PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE; 470af051161SJung-uk Kim PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 471af051161SJung-uk Kim break; 472af051161SJung-uk Kim 473af051161SJung-uk Kim case (AML_LOGICAL_NOT_OP): 474af051161SJung-uk Kim 475af051161SJung-uk Kim /* 476af051161SJung-uk Kim * The Package will be the predicate of the Case statement. 477af051161SJung-uk Kim * It's under: 478af051161SJung-uk Kim * LNOT 479af051161SJung-uk Kim * LEQUAL 480af051161SJung-uk Kim * MATCH 481af051161SJung-uk Kim * PACKAGE 482af051161SJung-uk Kim */ 483af051161SJung-uk Kim 484af051161SJung-uk Kim /* Get the LEqual Op from LNot */ 485af051161SJung-uk Kim 486af051161SJung-uk Kim TempOp = AcpiPsGetArg (TempOp, 0); 487af051161SJung-uk Kim 488af051161SJung-uk Kim /* Get the Match Op from LEqual */ 489af051161SJung-uk Kim 490af051161SJung-uk Kim TempOp = AcpiPsGetArg (TempOp, 0); 491af051161SJung-uk Kim 492af051161SJung-uk Kim /* Get the Package Op from Match */ 493af051161SJung-uk Kim 494af051161SJung-uk Kim PredicateOp = AcpiPsGetArg (TempOp, 0); 495af051161SJung-uk Kim 496af051161SJung-uk Kim /* Mark as parameter list for paren closing */ 497af051161SJung-uk Kim 498af051161SJung-uk Kim PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 499af051161SJung-uk Kim 500af051161SJung-uk Kim /* 501af051161SJung-uk Kim * The Package list would be too deeply indented if we 502af051161SJung-uk Kim * chose to simply ignore the all the parent opcodes, so 503af051161SJung-uk Kim * we rearrange the parse tree instead. 504af051161SJung-uk Kim */ 505af051161SJung-uk Kim 506af051161SJung-uk Kim /* 507af051161SJung-uk Kim * Save the second arg of the If/Else Op which is the 508af051161SJung-uk Kim * block code of code for this Case statement. 509af051161SJung-uk Kim */ 510af051161SJung-uk Kim TempOp = AcpiPsGetArg (CurrentOp, 1); 511af051161SJung-uk Kim 512af051161SJung-uk Kim /* 513af051161SJung-uk Kim * Move the Package Op to the child (predicate) of the 514af051161SJung-uk Kim * Case statement. 515af051161SJung-uk Kim */ 516af051161SJung-uk Kim CurrentOp->Common.Value.Arg = PredicateOp; 517af051161SJung-uk Kim PredicateOp->Common.Parent = CurrentOp; 518af051161SJung-uk Kim 519af051161SJung-uk Kim /* Add the block code */ 520af051161SJung-uk Kim 521af051161SJung-uk Kim PredicateOp->Common.Next = TempOp; 522af051161SJung-uk Kim break; 523af051161SJung-uk Kim 524af051161SJung-uk Kim default: 525af051161SJung-uk Kim 526af051161SJung-uk Kim /* Should never get here */ 527af051161SJung-uk Kim break; 528af051161SJung-uk Kim } 529af051161SJung-uk Kim 530af051161SJung-uk Kim /* Advance to next Case block */ 531af051161SJung-uk Kim 532af051161SJung-uk Kim CurrentOp = CurrentOp->Common.Next; 533af051161SJung-uk Kim } 534af051161SJung-uk Kim 535af051161SJung-uk Kim /* If CurrentOp is now an Else, then this is a Default block */ 536af051161SJung-uk Kim 537af051161SJung-uk Kim if (CurrentOp && CurrentOp->Common.AmlOpcode == AML_ELSE_OP) 538af051161SJung-uk Kim { 539af051161SJung-uk Kim CurrentOp->Common.DisasmOpcode = ACPI_DASM_DEFAULT; 540af051161SJung-uk Kim } 541af051161SJung-uk Kim 542af051161SJung-uk Kim /* 543af051161SJung-uk Kim * From the first If advance to the Break op. It's possible to 544af051161SJung-uk Kim * have an Else (Default) op here when there is only one Case 545af051161SJung-uk Kim * statement, so check for it. 546af051161SJung-uk Kim */ 547af051161SJung-uk Kim CurrentOp = StoreOp->Common.Next->Common.Next; 548f1db5ef7SJung-uk Kim if (!CurrentOp) 549f1db5ef7SJung-uk Kim { 550f1db5ef7SJung-uk Kim return (FALSE); 551f1db5ef7SJung-uk Kim } 552af051161SJung-uk Kim if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP) 553af051161SJung-uk Kim { 554af051161SJung-uk Kim CurrentOp = CurrentOp->Common.Next; 55590b566fdSJung-uk Kim if (!CurrentOp) 55690b566fdSJung-uk Kim { 55790b566fdSJung-uk Kim return (FALSE); 55890b566fdSJung-uk Kim } 559af051161SJung-uk Kim } 560af051161SJung-uk Kim 561af051161SJung-uk Kim /* Ignore the Break Op */ 562af051161SJung-uk Kim 563af051161SJung-uk Kim CurrentOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 564af051161SJung-uk Kim return (TRUE); 565af051161SJung-uk Kim } 566af051161SJung-uk Kim 567af051161SJung-uk Kim 568af051161SJung-uk Kim /******************************************************************************* 569af051161SJung-uk Kim * 570af051161SJung-uk Kim * FUNCTION: AcpiDmIsCaseBlock 571af051161SJung-uk Kim * 572af051161SJung-uk Kim * PARAMETERS: Op - Object to test 573af051161SJung-uk Kim * 574af051161SJung-uk Kim * RETURN: TRUE if Object is beginning of a Case block. 575af051161SJung-uk Kim * 576af051161SJung-uk Kim * DESCRIPTION: Determines if an Object is the beginning of a Case block for a 577af051161SJung-uk Kim * Switch/Case statement. Parse tree must be one of the following 578af051161SJung-uk Kim * forms: 579af051161SJung-uk Kim * 580af051161SJung-uk Kim * Else (Optional) 581af051161SJung-uk Kim * If 582af051161SJung-uk Kim * LEqual 583af051161SJung-uk Kim * -NamePath- _T_x 584af051161SJung-uk Kim * 585af051161SJung-uk Kim * Else (Optional) 586af051161SJung-uk Kim * If 587af051161SJung-uk Kim * LNot 588af051161SJung-uk Kim * LEqual 589af051161SJung-uk Kim * Match 590af051161SJung-uk Kim * Package 591af051161SJung-uk Kim * ByteConst 592af051161SJung-uk Kim * -NamePath- _T_x 593af051161SJung-uk Kim * 594af051161SJung-uk Kim ******************************************************************************/ 595af051161SJung-uk Kim 596af051161SJung-uk Kim static BOOLEAN 597af051161SJung-uk Kim AcpiDmIsCaseBlock ( 598af051161SJung-uk Kim ACPI_PARSE_OBJECT *Op) 599af051161SJung-uk Kim { 600af051161SJung-uk Kim ACPI_PARSE_OBJECT *CurrentOp; 601af051161SJung-uk Kim 602af051161SJung-uk Kim 603af051161SJung-uk Kim if (!Op) 604af051161SJung-uk Kim { 605af051161SJung-uk Kim return (FALSE); 606af051161SJung-uk Kim } 607af051161SJung-uk Kim 608af051161SJung-uk Kim /* Look for an If or ElseIf */ 609af051161SJung-uk Kim 610af051161SJung-uk Kim CurrentOp = Op; 611af051161SJung-uk Kim if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP) 612af051161SJung-uk Kim { 613af051161SJung-uk Kim CurrentOp = AcpiPsGetArg (CurrentOp, 0); 614af051161SJung-uk Kim if (!CurrentOp) 615af051161SJung-uk Kim { 616af051161SJung-uk Kim return (FALSE); 617af051161SJung-uk Kim } 618af051161SJung-uk Kim } 619af051161SJung-uk Kim 620af051161SJung-uk Kim if (!CurrentOp || CurrentOp->Common.AmlOpcode != AML_IF_OP) 621af051161SJung-uk Kim { 622af051161SJung-uk Kim return (FALSE); 623af051161SJung-uk Kim } 624af051161SJung-uk Kim 625af051161SJung-uk Kim /* Child must be LEqual or LNot */ 626af051161SJung-uk Kim 627af051161SJung-uk Kim CurrentOp = AcpiPsGetArg (CurrentOp, 0); 628af051161SJung-uk Kim if (!CurrentOp) 629af051161SJung-uk Kim { 630af051161SJung-uk Kim return (FALSE); 631af051161SJung-uk Kim } 632af051161SJung-uk Kim 633af051161SJung-uk Kim switch (CurrentOp->Common.AmlOpcode) 634af051161SJung-uk Kim { 635af051161SJung-uk Kim case (AML_LOGICAL_EQUAL_OP): 636af051161SJung-uk Kim 637af051161SJung-uk Kim /* Next child must be NamePath with string _T_ */ 638af051161SJung-uk Kim 639af051161SJung-uk Kim CurrentOp = AcpiPsGetArg (CurrentOp, 0); 640af051161SJung-uk Kim if (!CurrentOp || !CurrentOp->Common.Value.Name || 641af051161SJung-uk Kim strncmp(CurrentOp->Common.Value.Name, "_T_", 3)) 642af051161SJung-uk Kim { 643af051161SJung-uk Kim return (FALSE); 644af051161SJung-uk Kim } 645af051161SJung-uk Kim break; 646af051161SJung-uk Kim 647af051161SJung-uk Kim case (AML_LOGICAL_NOT_OP): 648af051161SJung-uk Kim 649af051161SJung-uk Kim /* Child of LNot must be LEqual op */ 650af051161SJung-uk Kim 651af051161SJung-uk Kim CurrentOp = AcpiPsGetArg (CurrentOp, 0); 652af051161SJung-uk Kim if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_LOGICAL_EQUAL_OP)) 653af051161SJung-uk Kim { 654af051161SJung-uk Kim return (FALSE); 655af051161SJung-uk Kim } 656af051161SJung-uk Kim 657af051161SJung-uk Kim /* Child of LNot must be Match op */ 658af051161SJung-uk Kim 659af051161SJung-uk Kim CurrentOp = AcpiPsGetArg (CurrentOp, 0); 660af051161SJung-uk Kim if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_MATCH_OP)) 661af051161SJung-uk Kim { 662af051161SJung-uk Kim return (FALSE); 663af051161SJung-uk Kim } 664af051161SJung-uk Kim 665af051161SJung-uk Kim /* First child of Match must be Package op */ 666af051161SJung-uk Kim 667af051161SJung-uk Kim CurrentOp = AcpiPsGetArg (CurrentOp, 0); 668af051161SJung-uk Kim if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_PACKAGE_OP)) 669af051161SJung-uk Kim { 670af051161SJung-uk Kim return (FALSE); 671af051161SJung-uk Kim } 672af051161SJung-uk Kim 673af051161SJung-uk Kim /* Third child of Match must be NamePath with string _T_ */ 674af051161SJung-uk Kim 675af051161SJung-uk Kim CurrentOp = AcpiPsGetArg (CurrentOp->Common.Parent, 2); 676af051161SJung-uk Kim if (!CurrentOp || !CurrentOp->Common.Value.Name || 677af051161SJung-uk Kim strncmp(CurrentOp->Common.Value.Name, "_T_", 3)) 678af051161SJung-uk Kim { 679af051161SJung-uk Kim return (FALSE); 680af051161SJung-uk Kim } 681af051161SJung-uk Kim break; 682af051161SJung-uk Kim 683af051161SJung-uk Kim default: 684af051161SJung-uk Kim 685af051161SJung-uk Kim return (FALSE); 686af051161SJung-uk Kim } 687af051161SJung-uk Kim 688af051161SJung-uk Kim return (TRUE); 689af051161SJung-uk Kim } 690