1*ed17e06eSJung-uk Kim /****************************************************************************** 2*ed17e06eSJung-uk Kim * 3*ed17e06eSJung-uk Kim * Module Name: dmdeferred - Disassembly of deferred AML opcodes 4*ed17e06eSJung-uk Kim * 5*ed17e06eSJung-uk Kim *****************************************************************************/ 6*ed17e06eSJung-uk Kim 7*ed17e06eSJung-uk Kim /* 8*ed17e06eSJung-uk Kim * Copyright (C) 2000 - 2012, Intel Corp. 9*ed17e06eSJung-uk Kim * All rights reserved. 10*ed17e06eSJung-uk Kim * 11*ed17e06eSJung-uk Kim * Redistribution and use in source and binary forms, with or without 12*ed17e06eSJung-uk Kim * modification, are permitted provided that the following conditions 13*ed17e06eSJung-uk Kim * are met: 14*ed17e06eSJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15*ed17e06eSJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16*ed17e06eSJung-uk Kim * without modification. 17*ed17e06eSJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*ed17e06eSJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19*ed17e06eSJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20*ed17e06eSJung-uk Kim * including a substantially similar Disclaimer requirement for further 21*ed17e06eSJung-uk Kim * binary redistribution. 22*ed17e06eSJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23*ed17e06eSJung-uk Kim * of any contributors may be used to endorse or promote products derived 24*ed17e06eSJung-uk Kim * from this software without specific prior written permission. 25*ed17e06eSJung-uk Kim * 26*ed17e06eSJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27*ed17e06eSJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28*ed17e06eSJung-uk Kim * Software Foundation. 29*ed17e06eSJung-uk Kim * 30*ed17e06eSJung-uk Kim * NO WARRANTY 31*ed17e06eSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*ed17e06eSJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*ed17e06eSJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*ed17e06eSJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*ed17e06eSJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*ed17e06eSJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*ed17e06eSJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*ed17e06eSJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*ed17e06eSJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*ed17e06eSJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*ed17e06eSJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42*ed17e06eSJung-uk Kim */ 43*ed17e06eSJung-uk Kim 44*ed17e06eSJung-uk Kim 45*ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 46*ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 47*ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h> 48*ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 49*ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h> 50*ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 51*ed17e06eSJung-uk Kim 52*ed17e06eSJung-uk Kim #define _COMPONENT ACPI_CA_DISASSEMBLER 53*ed17e06eSJung-uk Kim ACPI_MODULE_NAME ("dmdeferred") 54*ed17e06eSJung-uk Kim 55*ed17e06eSJung-uk Kim 56*ed17e06eSJung-uk Kim /* Local prototypes */ 57*ed17e06eSJung-uk Kim 58*ed17e06eSJung-uk Kim static ACPI_STATUS 59*ed17e06eSJung-uk Kim AcpiDmDeferredParse ( 60*ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 61*ed17e06eSJung-uk Kim UINT8 *Aml, 62*ed17e06eSJung-uk Kim UINT32 AmlLength); 63*ed17e06eSJung-uk Kim 64*ed17e06eSJung-uk Kim 65*ed17e06eSJung-uk Kim /****************************************************************************** 66*ed17e06eSJung-uk Kim * 67*ed17e06eSJung-uk Kim * FUNCTION: AcpiDmParseDeferredOps 68*ed17e06eSJung-uk Kim * 69*ed17e06eSJung-uk Kim * PARAMETERS: Root - Root of the parse tree 70*ed17e06eSJung-uk Kim * 71*ed17e06eSJung-uk Kim * RETURN: Status 72*ed17e06eSJung-uk Kim * 73*ed17e06eSJung-uk Kim * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.) 74*ed17e06eSJung-uk Kim * 75*ed17e06eSJung-uk Kim *****************************************************************************/ 76*ed17e06eSJung-uk Kim 77*ed17e06eSJung-uk Kim ACPI_STATUS 78*ed17e06eSJung-uk Kim AcpiDmParseDeferredOps ( 79*ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *Root) 80*ed17e06eSJung-uk Kim { 81*ed17e06eSJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 82*ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *Op = Root; 83*ed17e06eSJung-uk Kim ACPI_STATUS Status; 84*ed17e06eSJung-uk Kim 85*ed17e06eSJung-uk Kim 86*ed17e06eSJung-uk Kim ACPI_FUNCTION_NAME (DmParseDeferredOps); 87*ed17e06eSJung-uk Kim 88*ed17e06eSJung-uk Kim 89*ed17e06eSJung-uk Kim /* Traverse the entire parse tree */ 90*ed17e06eSJung-uk Kim 91*ed17e06eSJung-uk Kim while (Op) 92*ed17e06eSJung-uk Kim { 93*ed17e06eSJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 94*ed17e06eSJung-uk Kim if (!(OpInfo->Flags & AML_DEFER)) 95*ed17e06eSJung-uk Kim { 96*ed17e06eSJung-uk Kim Op = AcpiPsGetDepthNext (Root, Op); 97*ed17e06eSJung-uk Kim continue; 98*ed17e06eSJung-uk Kim } 99*ed17e06eSJung-uk Kim 100*ed17e06eSJung-uk Kim /* Now we know we have a deferred opcode */ 101*ed17e06eSJung-uk Kim 102*ed17e06eSJung-uk Kim switch (Op->Common.AmlOpcode) 103*ed17e06eSJung-uk Kim { 104*ed17e06eSJung-uk Kim case AML_METHOD_OP: 105*ed17e06eSJung-uk Kim case AML_BUFFER_OP: 106*ed17e06eSJung-uk Kim case AML_PACKAGE_OP: 107*ed17e06eSJung-uk Kim case AML_VAR_PACKAGE_OP: 108*ed17e06eSJung-uk Kim 109*ed17e06eSJung-uk Kim Status = AcpiDmDeferredParse (Op, Op->Named.Data, Op->Named.Length); 110*ed17e06eSJung-uk Kim if (ACPI_FAILURE (Status)) 111*ed17e06eSJung-uk Kim { 112*ed17e06eSJung-uk Kim return (Status); 113*ed17e06eSJung-uk Kim } 114*ed17e06eSJung-uk Kim break; 115*ed17e06eSJung-uk Kim 116*ed17e06eSJung-uk Kim /* We don't need to do anything for these deferred opcodes */ 117*ed17e06eSJung-uk Kim 118*ed17e06eSJung-uk Kim case AML_REGION_OP: 119*ed17e06eSJung-uk Kim case AML_DATA_REGION_OP: 120*ed17e06eSJung-uk Kim case AML_CREATE_QWORD_FIELD_OP: 121*ed17e06eSJung-uk Kim case AML_CREATE_DWORD_FIELD_OP: 122*ed17e06eSJung-uk Kim case AML_CREATE_WORD_FIELD_OP: 123*ed17e06eSJung-uk Kim case AML_CREATE_BYTE_FIELD_OP: 124*ed17e06eSJung-uk Kim case AML_CREATE_BIT_FIELD_OP: 125*ed17e06eSJung-uk Kim case AML_CREATE_FIELD_OP: 126*ed17e06eSJung-uk Kim case AML_BANK_FIELD_OP: 127*ed17e06eSJung-uk Kim 128*ed17e06eSJung-uk Kim break; 129*ed17e06eSJung-uk Kim 130*ed17e06eSJung-uk Kim default: 131*ed17e06eSJung-uk Kim ACPI_ERROR ((AE_INFO, "Unhandled deferred AML opcode [0x%.4X]", 132*ed17e06eSJung-uk Kim Op->Common.AmlOpcode)); 133*ed17e06eSJung-uk Kim break; 134*ed17e06eSJung-uk Kim } 135*ed17e06eSJung-uk Kim 136*ed17e06eSJung-uk Kim Op = AcpiPsGetDepthNext (Root, Op); 137*ed17e06eSJung-uk Kim } 138*ed17e06eSJung-uk Kim 139*ed17e06eSJung-uk Kim return (AE_OK); 140*ed17e06eSJung-uk Kim } 141*ed17e06eSJung-uk Kim 142*ed17e06eSJung-uk Kim 143*ed17e06eSJung-uk Kim /****************************************************************************** 144*ed17e06eSJung-uk Kim * 145*ed17e06eSJung-uk Kim * FUNCTION: AcpiDmDeferredParse 146*ed17e06eSJung-uk Kim * 147*ed17e06eSJung-uk Kim * PARAMETERS: Op - Root Op of the deferred opcode 148*ed17e06eSJung-uk Kim * Aml - Pointer to the raw AML 149*ed17e06eSJung-uk Kim * AmlLength - Length of the AML 150*ed17e06eSJung-uk Kim * 151*ed17e06eSJung-uk Kim * RETURN: Status 152*ed17e06eSJung-uk Kim * 153*ed17e06eSJung-uk Kim * DESCRIPTION: Parse one deferred opcode 154*ed17e06eSJung-uk Kim * (Methods, operation regions, etc.) 155*ed17e06eSJung-uk Kim * 156*ed17e06eSJung-uk Kim *****************************************************************************/ 157*ed17e06eSJung-uk Kim 158*ed17e06eSJung-uk Kim static ACPI_STATUS 159*ed17e06eSJung-uk Kim AcpiDmDeferredParse ( 160*ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 161*ed17e06eSJung-uk Kim UINT8 *Aml, 162*ed17e06eSJung-uk Kim UINT32 AmlLength) 163*ed17e06eSJung-uk Kim { 164*ed17e06eSJung-uk Kim ACPI_WALK_STATE *WalkState; 165*ed17e06eSJung-uk Kim ACPI_STATUS Status; 166*ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *SearchOp; 167*ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *StartOp; 168*ed17e06eSJung-uk Kim UINT32 BaseAmlOffset; 169*ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *NewRootOp; 170*ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *ExtraOp; 171*ed17e06eSJung-uk Kim 172*ed17e06eSJung-uk Kim 173*ed17e06eSJung-uk Kim ACPI_FUNCTION_TRACE (DmDeferredParse); 174*ed17e06eSJung-uk Kim 175*ed17e06eSJung-uk Kim 176*ed17e06eSJung-uk Kim if (!Aml || !AmlLength) 177*ed17e06eSJung-uk Kim { 178*ed17e06eSJung-uk Kim return_ACPI_STATUS (AE_OK); 179*ed17e06eSJung-uk Kim } 180*ed17e06eSJung-uk Kim 181*ed17e06eSJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing deferred opcode %s [%4.4s]\n", 182*ed17e06eSJung-uk Kim Op->Common.AmlOpName, (char *) &Op->Named.Name)); 183*ed17e06eSJung-uk Kim 184*ed17e06eSJung-uk Kim /* Need a new walk state to parse the AML */ 185*ed17e06eSJung-uk Kim 186*ed17e06eSJung-uk Kim WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); 187*ed17e06eSJung-uk Kim if (!WalkState) 188*ed17e06eSJung-uk Kim { 189*ed17e06eSJung-uk Kim return_ACPI_STATUS (AE_NO_MEMORY); 190*ed17e06eSJung-uk Kim } 191*ed17e06eSJung-uk Kim 192*ed17e06eSJung-uk Kim Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml, 193*ed17e06eSJung-uk Kim AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 194*ed17e06eSJung-uk Kim if (ACPI_FAILURE (Status)) 195*ed17e06eSJung-uk Kim { 196*ed17e06eSJung-uk Kim return_ACPI_STATUS (Status); 197*ed17e06eSJung-uk Kim } 198*ed17e06eSJung-uk Kim 199*ed17e06eSJung-uk Kim /* Parse the AML for this deferred opcode */ 200*ed17e06eSJung-uk Kim 201*ed17e06eSJung-uk Kim WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 202*ed17e06eSJung-uk Kim WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 203*ed17e06eSJung-uk Kim Status = AcpiPsParseAml (WalkState); 204*ed17e06eSJung-uk Kim 205*ed17e06eSJung-uk Kim /* 206*ed17e06eSJung-uk Kim * We need to update all of the AML offsets, since the parser thought 207*ed17e06eSJung-uk Kim * that the method began at offset zero. In reality, it began somewhere 208*ed17e06eSJung-uk Kim * within the ACPI table, at the BaseAmlOffset. Walk the entire tree that 209*ed17e06eSJung-uk Kim * was just created and update the AmlOffset in each Op. 210*ed17e06eSJung-uk Kim */ 211*ed17e06eSJung-uk Kim BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1; 212*ed17e06eSJung-uk Kim StartOp = (Op->Common.Value.Arg)->Common.Next; 213*ed17e06eSJung-uk Kim SearchOp = StartOp; 214*ed17e06eSJung-uk Kim 215*ed17e06eSJung-uk Kim while (SearchOp) 216*ed17e06eSJung-uk Kim { 217*ed17e06eSJung-uk Kim SearchOp->Common.AmlOffset += BaseAmlOffset; 218*ed17e06eSJung-uk Kim SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 219*ed17e06eSJung-uk Kim } 220*ed17e06eSJung-uk Kim 221*ed17e06eSJung-uk Kim /* 222*ed17e06eSJung-uk Kim * For Buffer and Package opcodes, link the newly parsed subtree 223*ed17e06eSJung-uk Kim * into the main parse tree 224*ed17e06eSJung-uk Kim */ 225*ed17e06eSJung-uk Kim switch (Op->Common.AmlOpcode) 226*ed17e06eSJung-uk Kim { 227*ed17e06eSJung-uk Kim case AML_BUFFER_OP: 228*ed17e06eSJung-uk Kim case AML_PACKAGE_OP: 229*ed17e06eSJung-uk Kim case AML_VAR_PACKAGE_OP: 230*ed17e06eSJung-uk Kim 231*ed17e06eSJung-uk Kim switch (Op->Common.AmlOpcode) 232*ed17e06eSJung-uk Kim { 233*ed17e06eSJung-uk Kim case AML_PACKAGE_OP: 234*ed17e06eSJung-uk Kim 235*ed17e06eSJung-uk Kim ExtraOp = Op->Common.Value.Arg; 236*ed17e06eSJung-uk Kim NewRootOp = ExtraOp->Common.Next; 237*ed17e06eSJung-uk Kim ACPI_FREE (ExtraOp); 238*ed17e06eSJung-uk Kim break; 239*ed17e06eSJung-uk Kim 240*ed17e06eSJung-uk Kim case AML_VAR_PACKAGE_OP: 241*ed17e06eSJung-uk Kim case AML_BUFFER_OP: 242*ed17e06eSJung-uk Kim default: 243*ed17e06eSJung-uk Kim 244*ed17e06eSJung-uk Kim NewRootOp = Op->Common.Value.Arg; 245*ed17e06eSJung-uk Kim break; 246*ed17e06eSJung-uk Kim } 247*ed17e06eSJung-uk Kim 248*ed17e06eSJung-uk Kim Op->Common.Value.Arg = NewRootOp->Common.Value.Arg; 249*ed17e06eSJung-uk Kim 250*ed17e06eSJung-uk Kim /* Must point all parents to the main tree */ 251*ed17e06eSJung-uk Kim 252*ed17e06eSJung-uk Kim StartOp = Op; 253*ed17e06eSJung-uk Kim SearchOp = StartOp; 254*ed17e06eSJung-uk Kim while (SearchOp) 255*ed17e06eSJung-uk Kim { 256*ed17e06eSJung-uk Kim if (SearchOp->Common.Parent == NewRootOp) 257*ed17e06eSJung-uk Kim { 258*ed17e06eSJung-uk Kim SearchOp->Common.Parent = Op; 259*ed17e06eSJung-uk Kim } 260*ed17e06eSJung-uk Kim 261*ed17e06eSJung-uk Kim SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 262*ed17e06eSJung-uk Kim } 263*ed17e06eSJung-uk Kim 264*ed17e06eSJung-uk Kim ACPI_FREE (NewRootOp); 265*ed17e06eSJung-uk Kim break; 266*ed17e06eSJung-uk Kim 267*ed17e06eSJung-uk Kim default: 268*ed17e06eSJung-uk Kim break; 269*ed17e06eSJung-uk Kim } 270*ed17e06eSJung-uk Kim 271*ed17e06eSJung-uk Kim return_ACPI_STATUS (AE_OK); 272*ed17e06eSJung-uk Kim } 273